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