File Coverage

blib/lib/Data/Sah/Util/Subschema.pm
Criterion Covered Total %
statement 52 52 100.0
branch 12 14 85.7
condition 5 8 62.5
subroutine 7 7 100.0
pod 1 1 100.0
total 77 82 93.9


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