File Coverage

blib/lib/Data/Sah/MoreUtils.pm
Criterion Covered Total %
statement 55 60 91.6
branch 24 36 66.6
condition 23 35 65.7
subroutine 12 14 85.7
pod 5 5 100.0
total 119 150 79.3


line stmt bran cond sub pod time code
1             package Data::Sah::MoreUtils;
2              
3 1     1   768 use 5.010001;
  1         4  
  1         42  
4 1     1   6 use strict;
  1         2  
  1         29  
5 1     1   5 use warnings;
  1         1  
  1         2389  
6              
7             our $VERSION = '0.01'; # VERSION
8              
9             require Exporter;
10             our @ISA = qw(Exporter);
11             our @EXPORT_OK = qw(get_type is_simple is_numeric is_collection is_ref);
12              
13             # XXX absorb and use metadata from Data::Sah::Type::*
14             my $type_metas = {
15             all => {scalar=>0, numeric=>0, ref=>0},
16             any => {scalar=>0, numeric=>0, ref=>0},
17             array => {scalar=>0, numeric=>0, ref=>1},
18             bool => {scalar=>1, numeric=>0, ref=>0},
19             buf => {scalar=>1, numeric=>0, ref=>0},
20             cistr => {scalar=>1, numeric=>0, ref=>0},
21             code => {scalar=>1, numeric=>0, ref=>1},
22             float => {scalar=>1, numeric=>1, ref=>0},
23             hash => {scalar=>0, numeric=>0, ref=>1},
24             int => {scalar=>1, numeric=>1, ref=>0},
25             num => {scalar=>1, numeric=>1, ref=>0},
26             obj => {scalar=>1, numeric=>0, ref=>1},
27             re => {scalar=>1, numeric=>0, ref=>1, simple=>1},
28             str => {scalar=>1, numeric=>0, ref=>0},
29             undef => {scalar=>1, numeric=>0, ref=>0},
30             };
31              
32             sub get_type {
33 79     79 1 113 my $sch = shift;
34              
35 79 100       202 if (ref($sch) eq 'ARRAY') {
36 24         45 $sch = $sch->[0];
37             }
38              
39 79 50 33     363 if (defined($sch) && !ref($sch)) {
40 79         146 $sch =~ s/\*\z//;
41 79         249 return $sch;
42             } else {
43 0         0 return undef;
44             }
45             }
46              
47             sub _normalize {
48 24     24   33 my ($sch, $opts) = @_;
49 24 50       55 return $sch if $opts->{schema_is_normalized};
50 24         1183 require Data::Sah;
51 24         90221 return Data::Sah::normalize_schema($sch);
52             }
53              
54             # for any|all to pass a criteria, we assume that all of the schemas in the 'of'
55             # clause must also pass (and there must not be '!of', 'of&', or that kind of
56             # thing.
57             sub _handle_any_all {
58 24     24   42 my ($sch, $opts, $crit) = @_;
59 24         41 $sch = _normalize($sch, $opts);
60 24 100       4585 return 0 if $sch->[1]{'of.op'};
61 16         29 my $of = $sch->[1]{of};
62 16 100 66     150 return 0 unless $of && ref($of) eq 'ARRAY' && @$of;
      100        
63 8         19 for (@$of) {
64 14 100       27 return 0 unless $crit->($_);
65             }
66 4         25 1;
67             }
68              
69             sub is_simple {
70 33     33 1 1225 my ($sch, $opts) = @_;
71 33   50     148 $opts //= {};
72              
73 33 50       62 my $type = get_type($sch) or return undef;
74 33 50       100 my $tmeta = $type_metas->{$type} or return undef;
75 33 100 100     128 if ($type eq 'any' || $type eq 'all') {
76 12     8   67 return _handle_any_all($sch, $opts, sub { is_simple(shift) });
  8         18  
77             }
78 21   100     205 return $tmeta->{simple} // ($tmeta->{scalar} && !$tmeta->{ref});
      66        
79             }
80              
81             sub is_collection {
82 31     31 1 2010 my ($sch, $opts) = @_;
83 31   50     138 $opts //= {};
84              
85 31 50       57 my $type = get_type($sch) or return undef;
86 31 50       90 my $tmeta = $type_metas->{$type} or return undef;
87 31 100 100     128 if ($type eq 'any' || $type eq 'all') {
88 12     6   54 return _handle_any_all($sch, $opts, sub { is_collection(shift) });
  6         14  
89             }
90 19         123 return !$tmeta->{scalar};
91             }
92              
93             sub is_numeric {
94 9     9 1 1960 my ($sch, $opts) = @_;
95 9   50     41 $opts //= {};
96              
97 9 50       18 my $type = get_type($sch) or return undef;
98 9 50       24 my $tmeta = $type_metas->{$type} or return undef;
99 9 50 33     208 if ($type eq 'any' || $type eq 'all') {
100 0     0   0 return _handle_any_all($sch, $opts, sub { is_numeric(shift) });
  0         0  
101             }
102 9         61 return $tmeta->{numeric};
103             }
104              
105             sub is_ref {
106 6     6 1 1667 my ($sch, $opts) = @_;
107 6   50     47 $opts //= {};
108              
109 6 50       22 my $type = get_type($sch) or return undef;
110 6 50       31 my $tmeta = $type_metas->{$type} or return undef;
111 6 50 33     41 if ($type eq 'any' || $type eq 'all') {
112 0     0   0 return _handle_any_all($sch, $opts, sub { is_ref(shift) });
  0         0  
113             }
114 6         47 return $tmeta->{ref};
115             }
116              
117             1;
118             # ABSTRACT: More utility functions related to Data::Sah
119              
120             __END__