File Coverage

blib/lib/Type/FromSah.pm
Criterion Covered Total %
statement 49 53 92.4
branch 5 6 83.3
condition n/a
subroutine 12 13 92.3
pod 1 1 100.0
total 67 73 91.7


line stmt bran cond sub pod time code
1 5     5   349934 use 5.010001;
  5         48  
2 5     5   22 use strict;
  5         7  
  5         84  
3 5     5   38 use warnings;
  5         22  
  5         305  
4              
5              
6             our $AUTHORITY = 'cpan:TOBYINK';
7             our $VERSION = '0.003';
8              
9             use Data::Sah qw( gen_validator normalize_schema );
10 5     5   2238 use Type::Tiny;
  5         23859  
  5         234  
11 5     5   2991 use Types::Standard qw( Item Optional );
  5         101524  
  5         144  
12 5     5   2566  
  5         354195  
  5         44  
13             use Exporter::Shiny qw( sah2type );
14 5     5   12251  
  5         1928  
  5         31  
15             state $pl = 'Data::Sah'->new->get_compiler("perl");
16            
17 7     7 1 690 my ( $schema, %opts ) = @_;
18             $schema = normalize_schema( $schema );
19 7         105774
20 7         31 return 'Type::Tiny'->new(
21             _data_sah => $schema,
22             parent => ( $schema->[1]{req} ? Item : Optional[Item] ),
23             constraint => sub {
24             state $coderef = gen_validator( $schema, coerce => 0 );
25             @_ = $_;
26 0     0   0 goto $coderef
27 0         0 },
28 0         0 inlined => sub {
29             my $varname = pop;
30             my $cd;
31 4     4   2882 my $handle_varname = '';
32 4         7
33 4         7 if ( $varname =~ /\A\$([^\W0-9]\w*)\z/ ) {
34             $cd = $pl->compile( schema => $schema, coerce => 0, data_name => "$1" );
35 4 50       24 }
36 0         0 else {
37             $cd = $pl->compile( schema => $schema, coerce => 0, data_name => 'data' );
38             $handle_varname = "my \$data = $varname;";
39 4         18 }
40 4         90552
41             my $code = $cd->{result};
42             my $load_modules = join '',
43 4         19 map $pl->stmt_require_module($_), @{ $cd->{modules} };
44            
45 4         15 return "do { $handle_varname $load_modules $code }";
  4         19  
46             },
47 4         176 constraint_generator => sub {
48             my @params = @_;
49             my $new_schema = [ $schema->[0], { %{ $schema->[1] }, @params } ];
50 1     1   4251 my $child = sah2type( $new_schema, parameters => \@params );
51 1         3 $child->check(undef); # force type checks to compile BEFORE parent
  1         5  
52 1         3 $child->{parent} = $Type::Tiny::parameterize_type;
53 1         87 return $child;
54 1         404 },
55 1         4 ( exists($schema->[1]{default})
56             ? ( type_default => sub { $schema->[1]{default} } )
57             : () ),
58 1     1   751 _build_coercion => sub {
59             my $coercion = shift;
60             my $f = gen_validator( $schema, { return_type => 'bool_valid+val' } );
61 2     2   1212 $coercion->add_type_coercions(
62 2         10 Item() => sub {
63             my ( undef, $new ) = @{ $f->($_) };
64             return $new;
65 1         579 },
  1         17  
66 1         3928 );
67             $coercion->freeze;
68 2         448406 },
69 2         1644 %opts,
70             );
71 7 100       784 }
    100          
72              
73             1;
74              
75              
76             =pod
77              
78             =encoding utf-8
79              
80             =head1 NAME
81              
82             Type::FromSah - create an efficient Type::Tiny type constraint from a Data::Sah schema
83              
84             =head1 SYNOPSIS
85              
86             package My::Types {
87             use Type::Library -base;
88             use Type::FromSah qw( sah2type );
89            
90             __PACKAGE__->add_type(
91             sah2type( [ "int", min => 1, max => 10 ], name => 'SmallInt' )
92             );
93             }
94            
95             use MyTypes qw(SmallInt);
96            
97             SmallInt->assert_valid( 7 );
98              
99             =head1 DESCRIPTION
100              
101             =head2 Functions
102              
103             This module exports one function.
104              
105             =head3 C<< sah2type( $schema, %options ) >>
106              
107             Takes a L<Data::Sah> schema (which should be an arrayref), and generates
108             a L<Type::Tiny> type constraint object for it. Additional key-value pairs
109             will be passed to the Type::Tiny constructor.
110              
111             =head1 BUGS
112              
113             Please report any bugs to
114             L<http://rt.cpan.org/Dist/Display.html?Queue=Type-FromSah>.
115              
116             =head1 SEE ALSO
117              
118             L<Data::Sah>, L<Type::Tiny>.
119              
120             =head1 AUTHOR
121              
122             Toby Inkster E<lt>tobyink@cpan.orgE<gt>.
123              
124             =head1 COPYRIGHT AND LICENCE
125              
126             This software is copyright (c) 2022 by Toby Inkster.
127              
128             This is free software; you can redistribute it and/or modify it under
129             the same terms as the Perl 5 programming language system itself.
130              
131              
132             =head1 DISCLAIMER OF WARRANTIES
133              
134             THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
135             WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
136             MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
137