File Coverage

blib/lib/Data/Sah/Util/Subschema.pm
Criterion Covered Total %
statement 50 50 100.0
branch 11 12 91.6
condition 3 6 50.0
subroutine 7 7 100.0
pod 1 1 100.0
total 72 76 94.7


line stmt bran cond sub pod time code
1             package Data::Sah::Util::Subschema;
2              
3             our $DATE = '2016-07-20'; # DATE
4             our $VERSION = '0.003'; # VERSION
5              
6 1     1   502 use 5.010001;
  1         2  
7 1     1   3 use strict;
  1         1  
  1         13  
8 1     1   3 use warnings;
  1         1  
  1         18  
9              
10 1     1   439 use Data::Sah::Normalize qw(normalize_schema);
  1         1217  
  1         68  
11 1     1   395 use Data::Sah::Resolve qw(resolve_schema);
  1         777  
  1         47  
12              
13 1     1   4 use Exporter qw(import);
  1         1  
  1         293  
14             our @EXPORT_OK = qw(extract_subschemas);
15              
16             my %clausemeta_cache; # key = TYPE.CLAUSE
17              
18             sub extract_subschemas {
19 7 100   7 1 31 my $opts = ref($_[0]) eq 'HASH' ? shift : {};
20 7         9 my $sch = shift;
21              
22 7 50       14 unless ($opts->{schema_is_normalized}) {
23 7         18 $sch = normalize_schema($sch);
24             }
25              
26 7         243 my $res = resolve_schema(
27             {schema_is_normalized => 1},
28             $sch);
29              
30 7         20387 my $typeclass = "Data::Sah::Type::$res->[0]";
31 7         26 (my $typeclass_pm = "$typeclass.pm") =~ s!::!/!g;
32 7         31 require $typeclass_pm;
33              
34             # XXX handle def and/or resolve schema into builtin types. for now we only
35             # have one clause set because we don't handle those.
36 7         7 my @clsets = @{ $res->[1] };
  7         12  
37              
38 7         7 my @res;
39 7         10 for my $clset (@clsets) {
40 4         6 for my $clname (keys %$clset) {
41 6 100       26 next unless $clname =~ /\A[A-Za-z][A-Za-z0-9_]*\z/;
42 5         10 my $cache_key = "$sch->[0].$clname";
43 5         6 my $clmeta = $clausemeta_cache{$cache_key};
44 5 100       9 unless ($clmeta) {
45 4         6 my $meth = "clausemeta_$clname";
46             $clmeta = $clausemeta_cache{$cache_key} =
47 4         5 $typeclass->${\("clausemeta_$clname")};
  4         30  
48             }
49 5 100       26 next unless $clmeta->{subschema};
50 3         5 my $op = $clset->{"$clname.op"};
51 3         3 my @clvalues;
52 3 100 33     13 if (defined($op) && ($op eq 'or' || $op eq 'and')) {
      66        
53 1         1 @clvalues = @{ $clset->{$clname} };
  1         3  
54             } else {
55 2         4 @clvalues = ( $clset->{$clname} );
56             }
57 3         4 for my $clvalue (@clvalues) {
58 4         11 my @subsch = $clmeta->{subschema}->($clvalue);
59 4         15 push @res, @subsch;
60 4         4 push @res, map { extract_subschemas($opts, $_) } @subsch;
  5         15  
61             }
62             }
63             }
64              
65 7         45 @res;
66             }
67              
68             1;
69             # ABSTRACT: Extract subschemas from a schema
70              
71             __END__
72              
73             =pod
74              
75             =encoding UTF-8
76              
77             =head1 NAME
78              
79             Data::Sah::Util::Subschema - Extract subschemas from a schema
80              
81             =head1 VERSION
82              
83             This document describes version 0.003 of Data::Sah::Util::Subschema (from Perl distribution Data-Sah-Util-Subschema), released on 2016-07-20.
84              
85             =head1 SYNOPSIS
86              
87             use Data::Sah::Util::Subschema qw(extract_subschemas)
88              
89             my $subschemas = extract_subschemas([array => of=>"int*"]);
90             # => ("int*")
91              
92             $subschemas = extract_subschemas([any => of=>["int*", [array => of=>"int"]]]);
93             # => ("int*", [array => of=>"int"], "int")
94              
95             =head1 DESCRIPTION
96              
97             =head1 FUNCTIONS
98              
99             =head2 extract_subschemas([ \%opts, ] $sch) => list
100              
101             Extract all subschemas found inside Sah schema C<$sch>. Schema will be
102             normalized first, then schemas from all clauses which contains subschemas will
103             be collected recursively.
104              
105             Known options:
106              
107             =over
108              
109             =item * schema_is_normalized => bool (default: 0)
110              
111             When set to true, function will skip normalizing schema and assume input schema
112             is normalized.
113              
114             =back
115              
116             =head1 HOMEPAGE
117              
118             Please visit the project's homepage at L<https://metacpan.org/release/Data-Sah-Util-Subschema>.
119              
120             =head1 SOURCE
121              
122             Source repository is at L<https://github.com/perlancar/perl-Data-Sah-Util-Subschema>.
123              
124             =head1 BUGS
125              
126             Please report any bugs or feature requests on the bugtracker website L<https://rt.cpan.org/Public/Dist/Display.html?Name=Data-Sah-Util-Subschema>
127              
128             When submitting a bug or request, please include a test-file or a
129             patch to an existing test-file that illustrates the bug or desired
130             feature.
131              
132             =head1 SEE ALSO
133              
134             L<Sah>, L<Data::Sah>
135              
136             =head1 AUTHOR
137              
138             perlancar <perlancar@cpan.org>
139              
140             =head1 COPYRIGHT AND LICENSE
141              
142             This software is copyright (c) 2016 by perlancar@cpan.org.
143              
144             This is free software; you can redistribute it and/or modify it under
145             the same terms as the Perl 5 programming language system itself.
146              
147             =cut