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   835644 use 5.010001;
  5         55  
2 5     5   26 use strict;
  5         7  
  5         114  
3 5     5   37 use warnings;
  5         18  
  5         362  
4              
5              
6             our $AUTHORITY = 'cpan:TOBYINK';
7             our $VERSION = '0.005';
8              
9             use Data::Sah qw( gen_validator normalize_schema );
10 5     5   2336 use Type::Tiny;
  5         25503  
  5         361  
11 5     5   3417 use Types::Standard qw( Item Optional );
  5         108746  
  5         194  
12 5     5   3277  
  5         373995  
  5         58  
13             use Exporter::Shiny qw( sah2type );
14 5     5   13704  
  5         2247  
  5         33  
15             state $pl = 'Data::Sah'->new->get_compiler("perl");
16            
17 7     7 1 783 my ( $schema, %opts ) = @_;
18             $schema = normalize_schema( $schema );
19 7         106290
20 7         36 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   3203 my $handle_varname = '';
32 4         8
33 4         11 if ( $varname =~ /\A\$([^\W0-9]\w*)\z/ ) {
34             $cd = $pl->compile( schema => $schema, coerce => 0, data_name => "$1" );
35 4 50       26 }
36 0         0 else {
37             $cd = $pl->compile( schema => $schema, coerce => 0, data_name => 'data' );
38             $handle_varname = "my \$data = $varname;";
39 4         35 }
40 4         95406
41             my $code = $cd->{result};
42             my $load_modules = join '',
43 4         26 map $pl->stmt_require_module($_), @{ $cd->{modules} };
44            
45 4         8 return "do { $handle_varname $load_modules $code }";
  4         19  
46             },
47 4         212 constraint_generator => sub {
48             my @params = @_;
49             my $new_schema = [ $schema->[0], { %{ $schema->[1] }, @params } ];
50 1     1   5062 my $child = sah2type( $new_schema, parameters => \@params );
51 1         3 $child->check(undef); # force type checks to compile BEFORE parent
  1         5  
52 1         6 $child->{parent} = $Type::Tiny::parameterize_type;
53 1         114 return $child;
54 1         732 },
55 1         6 ( exists($schema->[1]{default})
56             ? ( type_default => sub { $schema->[1]{default} } )
57             : () ),
58 1     1   829 _build_coercion => sub {
59             my $coercion = shift;
60             my $f = gen_validator( $schema, { return_type => 'bool_valid+val' } );
61 2     2   1309 $coercion->add_type_coercions(
62 2         12 Item() => sub {
63             my ( undef, $new ) = @{ $f->($_) };
64             return $new;
65 1         605 },
  1         17  
66 1         4227 );
67             $coercion->freeze;
68 2         14042 },
69 2         1906 %opts,
70             );
71 7 100       837 }
    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