File Coverage

blib/lib/Data/Sah/Compiler/perl/TH/duration.pm
Criterion Covered Total %
statement 24 73 32.8
branch 1 50 2.0
condition 1 2 50.0
subroutine 7 9 77.7
pod 0 3 0.0
total 33 137 24.0


line stmt bran cond sub pod time code
1              
2             use 5.010;
3 1     1   14 use strict;
  1         4  
4 1     1   5 use warnings;
  1         1  
  1         17  
5 1     1   4 #use Log::Any '$log';
  1         3  
  1         22  
6              
7             use Mo qw(build default);
8 1     1   5 use Role::Tiny::With;
  1         1  
  1         5  
9 1     1   233 use Scalar::Util qw(blessed looks_like_number);
  1         2  
  1         39  
10 1     1   5  
  1         1  
  1         990  
11             extends 'Data::Sah::Compiler::perl::TH';
12             with 'Data::Sah::Type::duration';
13              
14             our $AUTHORITY = 'cpan:PERLANCAR'; # AUTHORITY
15             our $DATE = '2022-08-20'; # DATE
16             our $DIST = 'Data-Sah'; # DIST
17             our $VERSION = '0.912'; # VERSION
18              
19             my ($self, $cd) = @_;
20             my $c = $self->compiler;
21 8     8 0 14 my $dt = $cd->{data_term};
22 8         34  
23 8         35 $cd->{coerce_to} = $cd->{nschema}[1]{"x.perl.coerce_to"} // 'float(secs)';
24              
25 8   50     28 my $coerce_to = $cd->{coerce_to};
26              
27 8         13 if ($coerce_to eq 'float(secs)') {
28             $cd->{_ccl_check_type} = "!ref($dt) && $dt =~ /\\A[0-9]+(?:\.[0-9]+)?\\z/"; # XXX no support exp notation for yet?
29 8 50       14 } elsif ($coerce_to eq 'DateTime::Duration') {
    0          
30 8         22 $c->add_runtime_module($cd, 'Scalar::Util');
31             $cd->{_ccl_check_type} = "Scalar::Util::blessed($dt) && $dt\->isa('DateTime::Duration')";
32 0           } else {
33 0           die "BUG: Unknown coerce_to value '$coerce_to', use either ".
34             "float(secs) or DateTime::Duration";
35 0           }
36             }
37              
38             my ($self, $which, $cd) = @_;
39             my $c = $self->compiler;
40             my $cv = $cd->{cl_value};
41 0     0 0   my $ct = $cd->{cl_term};
42 0           my $dt = $cd->{data_term};
43 0            
44 0           if ($cd->{cl_is_expr}) {
45 0           # i'm lazy, technical debt
46             $c->_die($cd, "duration's comparison with expression not yet supported");
47 0 0         }
48              
49 0           my $coerce_to = $cd->{coerce_to};
50             if ($coerce_to eq 'float(secs)') {
51             if ($which eq 'is') {
52 0           $c->add_ccl($cd, "$dt == $ct"); # XXX yeah we're not supposed to use == with floats
53 0 0         } elsif ($which eq 'in') {
    0          
54 0 0         $c->add_runtime_module('List::Util');
    0          
55 0           $c->add_ccl($cd, "List::Util::first(sub{$dt == \$_}, $ct)"); # XXX yeah we're not supposed to use == with floats
56             }
57 0           } elsif ($coerce_to eq 'DateTime::Duration') {
58 0           # we need to express this like this because if we just use the raw $cv
59             # (dump) it will be unwieldy
60             my $ect = join(
61             "",
62             "DateTime::Duration->new(",
63 0           "years => " .$cv->years.",",
64             "months => " .$cv->months.",",
65             "weeks => " .$cv->weeks.",",
66             "days => " .$cv->days.",",
67             "hours => " .$cv->hours.",",
68             "minutes => ".$cv->minutes.",",
69             "seconds => ".$cv->seconds.",",
70             ")",
71             );
72              
73             if ($which eq 'is') {
74             $c->add_ccl($cd, "DateTime::Duration->compare($dt, $ect)==0");
75             } elsif ($which eq 'in') {
76 0 0         $c->add_runtime_module('List::Util');
    0          
77 0           $c->add_ccl($cd, "List::Util::first(sub{DateTime::Duration->compare($dt, \$_)==0}, $ect)");
78             }
79 0           }
80 0           }
81              
82             my ($self, $which, $cd) = @_;
83             my $c = $self->compiler;
84             my $cv = $cd->{cl_value};
85             my $ct = $cd->{cl_term};
86 0     0 0   my $dt = $cd->{data_term};
87 0            
88 0           if ($cd->{cl_is_expr}) {
89 0           # i'm lazy, technical debt
90 0           $c->_die($cd, "duration's comparison with expression not yet supported");
91             }
92 0 0          
93             my $coerce_to = $cd->{coerce_to};
94 0           if ($coerce_to eq 'float(secs)') {
95             if ($which eq 'min') {
96             $c->add_ccl($cd, "$dt >= $cv");
97 0           } elsif ($which eq 'xmin') {
98 0 0         $c->add_ccl($cd, "$dt > $cv");
    0          
99 0 0         } elsif ($which eq 'max') {
    0          
    0          
    0          
    0          
    0          
100 0           $c->add_ccl($cd, "$dt <= $cv");
101             } elsif ($which eq 'xmax') {
102 0           $c->add_ccl($cd, "$dt < $cv");
103             } elsif ($which eq 'between') {
104 0           $c->add_ccl($cd, "$dt >= $cv->[0] && $dt <= $cv->[1]");
105             } elsif ($which eq 'xbetween') {
106 0           $c->add_ccl($cd, "$dt > $cv->[0] && $dt < $cv->[1]");
107             }
108 0           } elsif ($coerce_to eq 'DateTime::Duration') {
109             # we need to express this like this because if we just use the raw $cv
110 0           # (dump) it will be unwieldy
111             my ($ect, $ect0, $ect1);
112             if (ref($cv) eq 'ARRAY') {
113             $ect0 = join(
114             "",
115 0           "DateTime::Duration->new(",
116 0 0         "years => " .$cv->[0]->years.",",
117 0           "months => " .$cv->[0]->months.",",
118             "weeks => " .$cv->[0]->weeks.",",
119             "days => " .$cv->[0]->days.",",
120             "hours => " .$cv->[0]->hours.",",
121             "minutes => ".$cv->[0]->minutes.",",
122             "seconds => ".$cv->[0]->seconds.",",
123             ")",
124             );
125             $ect1 = join(
126             "",
127             "DateTime::Duration->new(",
128             "years => " .$cv->[1]->years.",",
129 0           "months => " .$cv->[1]->months.",",
130             "weeks => " .$cv->[1]->weeks.",",
131             "days => " .$cv->[1]->days.",",
132             "hours => " .$cv->[1]->hours.",",
133             "minutes => ".$cv->[1]->minutes.",",
134             "seconds => ".$cv->[1]->seconds.",",
135             ")",
136             );
137             } else {
138             $ect = join(
139             "",
140             "DateTime::Duration->new(",
141             "years => " .$cv->years.",",
142 0           "months => " .$cv->months.",",
143             "weeks => " .$cv->weeks.",",
144             "days => " .$cv->days.",",
145             "hours => " .$cv->hours.",",
146             "minutes => ".$cv->minutes.",",
147             "seconds => ".$cv->seconds.",",
148             ")",
149             );
150             }
151              
152             if ($which eq 'min') {
153             $c->add_ccl($cd, "DateTime->compare($dt, $ect) >= 0");
154             } elsif ($which eq 'xmin') {
155             $c->add_ccl($cd, "DateTime->compare($dt, $ect) > 0");
156 0 0         } elsif ($which eq 'max') {
    0          
    0          
    0          
    0          
    0          
157 0           $c->add_ccl($cd, "DateTime->compare($dt, $ect) <= 0");
158             } elsif ($which eq 'xmax') {
159 0           $c->add_ccl($cd, "DateTime->compare($dt, $ect) < 0");
160             } elsif ($which eq 'between') {
161 0           $c->add_ccl($cd, "DateTime->compare($dt, $ect0) >= 0 && DateTime->compare($dt, $ect1) <= 0");
162             } elsif ($which eq 'xbetween') {
163 0           $c->add_ccl($cd, "DateTime->compare($dt, $ect0) > 0 && DateTime->compare($dt, $ect1) < 0");
164             }
165 0           }
166             }
167 0            
168             1;
169             # ABSTRACT: perl's type handler for type "duration"
170              
171              
172             =pod
173              
174             =encoding UTF-8
175              
176             =head1 NAME
177              
178             Data::Sah::Compiler::perl::TH::duration - perl's type handler for type "duration"
179              
180             =head1 VERSION
181              
182             This document describes version 0.912 of Data::Sah::Compiler::perl::TH::duration (from Perl distribution Data-Sah), released on 2022-08-20.
183              
184             =head1 DESCRIPTION
185              
186             The C<duration> type in perl can be represented one of two choices: float
187             (secs), or L<DateTime::Duration> object.
188              
189             =for Pod::Coverage ^(clause_.+|superclause_.+|handle_.+|before_.+|after_.+)$
190              
191             =head1 HOMEPAGE
192              
193             Please visit the project's homepage at L<https://metacpan.org/release/Data-Sah>.
194              
195             =head1 SOURCE
196              
197             Source repository is at L<https://github.com/perlancar/perl-Data-Sah>.
198              
199             =head1 AUTHOR
200              
201             perlancar <perlancar@cpan.org>
202              
203             =head1 CONTRIBUTING
204              
205              
206             To contribute, you can send patches by email/via RT, or send pull requests on
207             GitHub.
208              
209             Most of the time, you don't need to build the distribution yourself. You can
210             simply modify the code, then test via:
211              
212             % prove -l
213              
214             If you want to build the distribution (e.g. to try to install it locally on your
215             system), you can install L<Dist::Zilla>,
216             L<Dist::Zilla::PluginBundle::Author::PERLANCAR>,
217             L<Pod::Weaver::PluginBundle::Author::PERLANCAR>, and sometimes one or two other
218             Dist::Zilla- and/or Pod::Weaver plugins. Any additional steps required beyond
219             that are considered a bug and can be reported to me.
220              
221             =head1 COPYRIGHT AND LICENSE
222              
223             This software is copyright (c) 2022, 2021, 2020, 2019, 2018, 2017, 2016, 2015, 2014, 2013, 2012 by perlancar <perlancar@cpan.org>.
224              
225             This is free software; you can redistribute it and/or modify it under
226             the same terms as the Perl 5 programming language system itself.
227              
228             =head1 BUGS
229              
230             Please report any bugs or feature requests on the bugtracker website L<https://rt.cpan.org/Public/Dist/Display.html?Name=Data-Sah>
231              
232             When submitting a bug or request, please include a test-file or a
233             patch to an existing test-file that illustrates the bug or desired
234             feature.
235              
236             =cut