| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  |  | 
| 2 |  |  |  |  |  |  | use 5.008003; | 
| 3 | 41 |  |  | 41 |  | 4759027 | use strict; | 
|  | 41 |  |  |  |  | 520 |  | 
| 4 | 41 |  |  | 41 |  | 213 | use warnings; | 
|  | 41 |  |  |  |  | 91 |  | 
|  | 41 |  |  |  |  | 837 |  | 
| 5 | 41 |  |  | 41 |  | 198 | use utf8; | 
|  | 41 |  |  |  |  | 102 |  | 
|  | 41 |  |  |  |  | 1341 |  | 
| 6 | 41 |  |  | 41 |  | 1873 |  | 
|  | 41 |  |  |  |  | 137 |  | 
|  | 41 |  |  |  |  | 343 |  | 
| 7 |  |  |  |  |  |  | BEGIN { | 
| 8 |  |  |  |  |  |  | $Types::XSD::AUTHORITY = 'cpan:TOBYINK'; | 
| 9 | 41 |  |  | 41 |  | 1959 | $Types::XSD::VERSION   = '0.008'; | 
| 10 | 41 |  |  |  |  | 983 | } | 
| 11 |  |  |  |  |  |  |  | 
| 12 |  |  |  |  |  |  | use B qw(perlstring); | 
| 13 | 41 |  |  | 41 |  | 267 | use Carp; | 
|  | 41 |  |  |  |  | 79 |  | 
|  | 41 |  |  |  |  | 2342 |  | 
| 14 | 41 |  |  | 41 |  | 241 | use DateTimeX::Auto qw( dt dur ); | 
|  | 41 |  |  |  |  | 95 |  | 
|  | 41 |  |  |  |  | 2264 |  | 
| 15 | 41 |  |  | 41 |  | 17082 | use DateTime::Incomplete (); | 
|  | 41 |  |  |  |  | 26337833 |  | 
|  | 41 |  |  |  |  | 775 |  | 
| 16 | 41 |  |  | 41 |  | 41004 | use Types::XSD::Lite 0.007 -base, -utils, -declare => qw( | 
|  | 41 |  |  |  |  | 2295247 |  | 
|  | 41 |  |  |  |  | 2382 |  | 
| 17 | 41 |  |  |  |  | 634 | Name NmToken NmTokens NCName Id IdRef IdRefs Entity Entities | 
| 18 |  |  |  |  |  |  | QName Notation Duration DateTime Time Date GYearMonth | 
| 19 |  |  |  |  |  |  | GYear GMonthDay GDay GMonth | 
| 20 |  |  |  |  |  |  | DateTimeStamp YearMonthDuration DayTimeDuration | 
| 21 |  |  |  |  |  |  | ); | 
| 22 | 41 |  |  | 41 |  | 23403 | use Types::Standard 2.000000 qw( StrMatch ); | 
|  | 41 |  |  |  |  | 8098820 |  | 
| 23 | 41 |  |  | 41 |  | 815370 | use XML::RegExp; | 
|  | 41 |  |  |  |  | 888 |  | 
|  | 41 |  |  |  |  | 254 |  | 
| 24 | 41 |  |  | 41 |  | 112646 |  | 
|  | 41 |  |  |  |  | 20025 |  | 
|  | 41 |  |  |  |  | 4714 |  | 
| 25 |  |  |  |  |  |  | push( our(@EXPORT_OK), qw( dt_cmp dur_cmp dt_parse dur_parse ) ); | 
| 26 |  |  |  |  |  |  |  | 
| 27 |  |  |  |  |  |  | BEGIN { | 
| 28 |  |  |  |  |  |  | *create_range_check = \&Types::XSD::Lite::create_range_check; | 
| 29 | 41 |  |  | 41 |  | 206 | *quick_range_check  = \&Types::XSD::Lite::quick_range_check; | 
| 30 | 41 |  |  |  |  | 131 | *hex_length         = \&Types::XSD::Lite::hex_length; | 
| 31 | 41 |  |  |  |  | 111 | *b64_length         = \&Types::XSD::Lite::b64_length; | 
| 32 | 41 |  |  |  |  | 92 | *with_facets        = \&Types::XSD::Lite::with_facets; | 
| 33 | 41 |  |  |  |  | 1725 | }; | 
| 34 |  |  |  |  |  |  |  | 
| 35 |  |  |  |  |  |  | use constant MAGIC_DATES => map dt($_), qw( 1696-09-01 1697-02-01 1903-03-01 1903-07-01 ); | 
| 36 | 41 |  |  | 41 |  | 283 | use constant MAGIC_TABLE => +{ "-1-1-1-1" => -1, "0000" => 0, "1111" => 1 }; | 
|  | 41 |  |  |  |  | 80 |  | 
|  | 41 |  |  |  |  | 284 |  | 
| 37 | 41 |  |  | 41 |  | 62105 |  | 
|  | 41 |  |  |  |  | 104 |  | 
|  | 41 |  |  |  |  | 94464 |  | 
| 38 |  |  |  |  |  |  | my @durations = do { | 
| 39 |  |  |  |  |  |  | local $SIG{__WARN__} = sub {}; | 
| 40 | 880 |  |  | 880 | 1 | 674299 | map ref($_) ? $_ : dur($_), @_[0,1]; | 
| 41 | 880 |  |  | 3520 |  | 6302 | }; | 
| 42 | 880 | 50 |  |  |  | 5599 | my $result = join q[], map "DateTime::Duration"->compare(@durations, $_), MAGIC_DATES; | 
| 43 |  |  |  |  |  |  | return MAGIC_TABLE->{$result} if exists MAGIC_TABLE->{$result}; | 
| 44 | 880 |  |  |  |  | 268268 | return undef; | 
| 45 | 880 | 50 |  |  |  | 5923028 | } | 
| 46 | 0 |  |  |  |  | 0 |  | 
| 47 |  |  |  |  |  |  | our @patterns;   my $pattern_i = -1; | 
| 48 |  |  |  |  |  |  | our @assertions; my $assertion_i = -1; | 
| 49 |  |  |  |  |  |  | my %facets = ( | 
| 50 |  |  |  |  |  |  | explicitTimezone => sub { | 
| 51 |  |  |  |  |  |  | my ($o, $var) = @_; | 
| 52 |  |  |  |  |  |  | return unless exists $o->{explicitTimezone}; | 
| 53 |  |  |  |  |  |  | my $etz = delete $o->{explicitTimezone}; | 
| 54 |  |  |  |  |  |  | return sprintf('%s =~ m/(?:Z|(?:[+-]\d{2}:?\d{2}))$/xism', $var) | 
| 55 |  |  |  |  |  |  | if lc($etz) eq 'required'; | 
| 56 |  |  |  |  |  |  | return sprintf('%s !~ m/(?:Z|(?:[+-]\d{2}:?\d{2}))$/xism', $var) | 
| 57 |  |  |  |  |  |  | if lc($etz) eq 'prohibited'; | 
| 58 |  |  |  |  |  |  | return '!!1' | 
| 59 |  |  |  |  |  |  | if lc($etz) eq 'optional'; | 
| 60 |  |  |  |  |  |  | croak "explicitTimezone facet expected to be 'required', 'prohibited' or 'optional'" | 
| 61 |  |  |  |  |  |  | }, | 
| 62 |  |  |  |  |  |  | maxInclusiveDuration => sub { | 
| 63 |  |  |  |  |  |  | my ($o, $var) = @_; | 
| 64 |  |  |  |  |  |  | return unless exists $o->{maxInclusive}; | 
| 65 |  |  |  |  |  |  | sprintf('(Types::XSD::dur_cmp(%s, %s)||0) <= 0', $var, perlstring delete $o->{maxInclusive}); | 
| 66 |  |  |  |  |  |  | }, | 
| 67 |  |  |  |  |  |  | minInclusiveDuration => sub { | 
| 68 |  |  |  |  |  |  | my ($o, $var) = @_; | 
| 69 |  |  |  |  |  |  | return unless exists $o->{minInclusive}; | 
| 70 |  |  |  |  |  |  | sprintf('(Types::XSD::dur_cmp(%s, %s)||0) >= 0', $var, perlstring delete $o->{minInclusive}); | 
| 71 |  |  |  |  |  |  | }, | 
| 72 |  |  |  |  |  |  | maxExclusiveDuration => sub { | 
| 73 |  |  |  |  |  |  | my ($o, $var) = @_; | 
| 74 |  |  |  |  |  |  | return unless exists $o->{maxExclusive}; | 
| 75 |  |  |  |  |  |  | sprintf('(Types::XSD::dur_cmp(%s, %s)||0) < 0', $var, perlstring delete $o->{maxExclusive}); | 
| 76 |  |  |  |  |  |  | }, | 
| 77 |  |  |  |  |  |  | minExclusiveDuration => sub { | 
| 78 |  |  |  |  |  |  | my ($o, $var) = @_; | 
| 79 |  |  |  |  |  |  | return unless exists $o->{minExclusive}; | 
| 80 |  |  |  |  |  |  | sprintf('(Types::XSD::dur_cmp(%s, %s)||0) > 0', $var, perlstring delete $o->{minExclusive}); | 
| 81 |  |  |  |  |  |  | }, | 
| 82 |  |  |  |  |  |  | maxInclusiveDT => sub { | 
| 83 |  |  |  |  |  |  | my ($o, $var) = @_; | 
| 84 |  |  |  |  |  |  | return unless exists $o->{maxInclusive}; | 
| 85 |  |  |  |  |  |  | sprintf('(Types::XSD::dt_cmp(%s, %s, %s)||0) <= 0', perlstring($Types::XSD::Lite::T), $var, perlstring delete $o->{maxInclusive}); | 
| 86 |  |  |  |  |  |  | }, | 
| 87 |  |  |  |  |  |  | minInclusiveDT => sub { | 
| 88 |  |  |  |  |  |  | my ($o, $var) = @_; | 
| 89 |  |  |  |  |  |  | return unless exists $o->{minInclusive}; | 
| 90 |  |  |  |  |  |  | sprintf('(Types::XSD::dt_cmp(%s, %s, %s)||0) >= 0', perlstring($Types::XSD::Lite::T), $var, perlstring delete $o->{minInclusive}); | 
| 91 |  |  |  |  |  |  | }, | 
| 92 |  |  |  |  |  |  | maxExclusiveDT => sub { | 
| 93 |  |  |  |  |  |  | my ($o, $var) = @_; | 
| 94 |  |  |  |  |  |  | return unless exists $o->{maxExclusive}; | 
| 95 |  |  |  |  |  |  | sprintf('(Types::XSD::dt_cmp(%s, %s, %s)||0) < 0', perlstring($Types::XSD::Lite::T), $var, perlstring delete $o->{maxExclusive}); | 
| 96 |  |  |  |  |  |  | }, | 
| 97 |  |  |  |  |  |  | minExclusiveDT => sub { | 
| 98 |  |  |  |  |  |  | my ($o, $var) = @_; | 
| 99 |  |  |  |  |  |  | return unless exists $o->{minExclusive}; | 
| 100 |  |  |  |  |  |  | sprintf('(Types::XSD::dt_cmp(%s, %s, %s)||0) > 0', perlstring($Types::XSD::Lite::T), $var, perlstring delete $o->{minExclusive}); | 
| 101 |  |  |  |  |  |  | }, | 
| 102 |  |  |  |  |  |  | ); | 
| 103 |  |  |  |  |  |  |  | 
| 104 |  |  |  |  |  |  | $Types::XSD::Lite::facets{$_} = $facets{$_} for keys %facets; | 
| 105 |  |  |  |  |  |  |  | 
| 106 |  |  |  |  |  |  | our @dtarr; | 
| 107 |  |  |  |  |  |  | my $i = -1; | 
| 108 |  |  |  |  |  |  | our $base_datetime = "DateTime"->new(year => 2000, month => 1, day => 1); # leap year, 31 day month | 
| 109 |  |  |  |  |  |  | our %dt_regexps; | 
| 110 |  |  |  |  |  |  |  | 
| 111 |  |  |  |  |  |  | my ( $name, $regexp, @fields ) = @_; | 
| 112 |  |  |  |  |  |  | my $j = ++$i; | 
| 113 |  |  |  |  |  |  | $dtarr[$j] = $regexp; | 
| 114 | 369 |  |  | 369 | 0 | 2400 |  | 
| 115 | 369 |  |  |  |  | 588 | my $inlined = sub { | 
| 116 | 369 |  |  |  |  | 702 | my $var = $_[1]; | 
| 117 |  |  |  |  |  |  | my @code; | 
| 118 |  |  |  |  |  |  | push @code, "do { my \$ok = 1;"; | 
| 119 | 6619 |  |  | 6619 |  | 639087 | push @code, sprintf( | 
| 120 | 6619 |  |  |  |  | 9101 | 'my (%s) = (%s =~ $Types::XSD::dtarr[%d]) or --$ok;', | 
| 121 | 6619 |  |  |  |  | 10855 | join(', ', map "\$$_", @fields), | 
| 122 | 6619 |  |  |  |  | 39920 | $var, | 
| 123 |  |  |  |  |  |  | $j, | 
| 124 |  |  |  |  |  |  | ); | 
| 125 |  |  |  |  |  |  | push @code, sprintf( | 
| 126 |  |  |  |  |  |  | '$ok and eval { "DateTime::Incomplete"->new(%s)->to_datetime(base => $Types::XSD::base_datetime) };', | 
| 127 |  |  |  |  |  |  | join(', ', map "$_ => \$$_", @fields), | 
| 128 | 6619 |  |  |  |  | 35069 | ); | 
| 129 |  |  |  |  |  |  | push @code, "}"; | 
| 130 |  |  |  |  |  |  | "@code"; | 
| 131 |  |  |  |  |  |  | }; | 
| 132 | 6619 |  |  |  |  | 12296 |  | 
| 133 | 6619 |  |  |  |  | 74899 | my $type = declare $name, | 
| 134 | 369 |  |  |  |  | 1333 | with_facets [qw( pattern whiteSpace enumeration maxInclusiveDT maxExclusiveDT minInclusiveDT minExclusiveDT explicitTimezone )], | 
| 135 |  |  |  |  |  |  | constraint => eval sprintf( 'sub { %s }', $inlined->(undef, '$_') ), | 
| 136 | 369 |  |  |  |  | 1277 | inlined    => $inlined; | 
| 137 |  |  |  |  |  |  |  | 
| 138 |  |  |  |  |  |  | $dt_regexps{$type} = [ $regexp, @fields ]; | 
| 139 |  |  |  |  |  |  | } | 
| 140 |  |  |  |  |  |  |  | 
| 141 | 369 |  |  |  |  | 192404 | my ($type, $a) = @_; | 
| 142 |  |  |  |  |  |  | my ($re, @fields) = @{ $dt_regexps{$type} }; | 
| 143 |  |  |  |  |  |  | my %d; | 
| 144 |  |  |  |  |  |  | @d{@fields} = ($a =~ $re); | 
| 145 | 0 |  |  | 0 | 1 | 0 | !defined($d{$_}) && delete($d{$_}) for @fields; | 
| 146 | 0 |  |  |  |  | 0 | "DateTime::Incomplete"->new(%d); | 
|  | 0 |  |  |  |  | 0 |  | 
| 147 | 0 |  |  |  |  | 0 | } | 
| 148 | 0 |  |  |  |  | 0 |  | 
| 149 | 0 |  | 0 |  |  | 0 | goto \&DateTimeX::Auto::dur; | 
| 150 | 0 |  |  |  |  | 0 | } | 
| 151 |  |  |  |  |  |  |  | 
| 152 |  |  |  |  |  |  | { | 
| 153 |  |  |  |  |  |  | my %cache; | 
| 154 | 0 |  |  | 0 | 1 | 0 | my ($lib, $v) = @_; | 
| 155 |  |  |  |  |  |  | for my $type (qw(DateTime Time Date GYearMonth GYear GMonthDay GDay GMonth)) { | 
| 156 |  |  |  |  |  |  | return $type if $lib->get_type($type)->check($v); | 
| 157 |  |  |  |  |  |  | } | 
| 158 |  |  |  |  |  |  | return $lib->get_type('DateTime'); | 
| 159 |  |  |  |  |  |  | } | 
| 160 | 6935 |  |  | 6935 |  | 14578 | my ($type, $a, $b) = @_; | 
| 161 | 6935 |  |  |  |  | 15322 | $type = __PACKAGE__->_detect_type($a) unless $type; | 
| 162 | 30905 | 100 |  |  |  | 539834 | $type = __PACKAGE__->get_type($type) unless ref $type; | 
| 163 |  |  |  |  |  |  | my $A = eval($cache{"$type;a"} ||= $type->inline_check('$a')); | 
| 164 | 0 |  |  |  |  | 0 | my $B = eval($cache{"$type;b"} ||= $type->inline_check('$b')); | 
| 165 |  |  |  |  |  |  | $A <=> $B; | 
| 166 |  |  |  |  |  |  | } | 
| 167 | 6935 |  |  | 6935 | 1 | 8659116 | } | 
| 168 | 6935 | 50 |  |  |  | 31493 |  | 
| 169 | 6935 | 50 |  |  |  | 3404854 | declare Name, | 
| 170 | 6935 |  | 66 |  |  | 93179 | with_facets [qw( length minLength maxLength pattern enumeration whiteSpace )], | 
| 171 | 6935 |  | 66 |  |  | 3362098 | as StrMatch[qr{\A(?:$XML::RegExp::Name)\z}sm]; | 
| 172 | 6935 |  |  |  |  | 3342939 |  | 
| 173 |  |  |  |  |  |  | declare NmToken, | 
| 174 |  |  |  |  |  |  | with_facets [qw( length minLength maxLength pattern enumeration whiteSpace )], | 
| 175 |  |  |  |  |  |  | as StrMatch[qr{\A(?:$XML::RegExp::NmToken)\z}sm]; | 
| 176 |  |  |  |  |  |  |  | 
| 177 |  |  |  |  |  |  | declare NmTokens, | 
| 178 |  |  |  |  |  |  | with_facets [qw( length minLength maxLength pattern enumeration whiteSpace )], | 
| 179 |  |  |  |  |  |  | as StrMatch[qr{\A(?:$XML::RegExp::NmToken)(?:\s+$XML::RegExp::NmToken)*\z}sm]; | 
| 180 |  |  |  |  |  |  |  | 
| 181 |  |  |  |  |  |  | declare NCName, | 
| 182 |  |  |  |  |  |  | with_facets [qw( length minLength maxLength pattern enumeration whiteSpace )], | 
| 183 |  |  |  |  |  |  | as StrMatch[qr{\A(?:$XML::RegExp::NCName)\z}sm]; | 
| 184 |  |  |  |  |  |  |  | 
| 185 |  |  |  |  |  |  | declare Id, | 
| 186 |  |  |  |  |  |  | with_facets [qw( length minLength maxLength pattern enumeration whiteSpace )], | 
| 187 |  |  |  |  |  |  | as NCName; | 
| 188 |  |  |  |  |  |  |  | 
| 189 |  |  |  |  |  |  | declare IdRef, | 
| 190 |  |  |  |  |  |  | with_facets [qw( length minLength maxLength pattern enumeration whiteSpace )], | 
| 191 |  |  |  |  |  |  | as NCName; | 
| 192 |  |  |  |  |  |  |  | 
| 193 |  |  |  |  |  |  | declare IdRefs, | 
| 194 |  |  |  |  |  |  | with_facets [qw( length minLength maxLength pattern enumeration whiteSpace )], | 
| 195 |  |  |  |  |  |  | as StrMatch[qr{\A(?:$XML::RegExp::NCName)(?:\s+$XML::RegExp::NCName)*\z}sm]; | 
| 196 |  |  |  |  |  |  |  | 
| 197 |  |  |  |  |  |  | declare Entity, | 
| 198 |  |  |  |  |  |  | with_facets [qw( length minLength maxLength pattern enumeration whiteSpace )], | 
| 199 |  |  |  |  |  |  | as NCName; | 
| 200 |  |  |  |  |  |  |  | 
| 201 |  |  |  |  |  |  | declare Entities, | 
| 202 |  |  |  |  |  |  | with_facets [qw( length minLength maxLength pattern enumeration whiteSpace )], | 
| 203 |  |  |  |  |  |  | as StrMatch[qr{\A(?:$XML::RegExp::NCName)(?:\s+$XML::RegExp::NCName)*\z}sm]; | 
| 204 |  |  |  |  |  |  |  | 
| 205 |  |  |  |  |  |  | declare QName, | 
| 206 |  |  |  |  |  |  | with_facets [qw( lengthQName minLengthQName maxLengthQName pattern enumeration whiteSpace )], | 
| 207 |  |  |  |  |  |  | as StrMatch[qr{\A(?:$XML::RegExp::QName)\z}sm]; | 
| 208 |  |  |  |  |  |  |  | 
| 209 |  |  |  |  |  |  | declare Notation, | 
| 210 |  |  |  |  |  |  | with_facets [qw( lengthQName minLengthQName maxLengthQName pattern enumeration whiteSpace )], | 
| 211 |  |  |  |  |  |  | as QName; | 
| 212 |  |  |  |  |  |  |  | 
| 213 |  |  |  |  |  |  | declare Duration, | 
| 214 |  |  |  |  |  |  | with_facets [qw( pattern whiteSpace enumeration maxInclusiveDuration maxExclusiveDuration minInclusiveDuration minExclusiveDuration )], | 
| 215 |  |  |  |  |  |  | as StrMatch[ | 
| 216 |  |  |  |  |  |  | qr{\A | 
| 217 |  |  |  |  |  |  | -? | 
| 218 |  |  |  |  |  |  | P | 
| 219 |  |  |  |  |  |  | (?:[0-9]+Y)? | 
| 220 |  |  |  |  |  |  | (?:[0-9]+M)? | 
| 221 |  |  |  |  |  |  | (?:[0-9]+D)? | 
| 222 |  |  |  |  |  |  | (?:T | 
| 223 |  |  |  |  |  |  | (?:[0-9]+H)? | 
| 224 |  |  |  |  |  |  | (?:[0-9]+M)? | 
| 225 |  |  |  |  |  |  | (?:[0-9]+(?:\.[0-9]+)?S)? | 
| 226 |  |  |  |  |  |  | )? | 
| 227 |  |  |  |  |  |  | \z}xism | 
| 228 |  |  |  |  |  |  | ]; | 
| 229 |  |  |  |  |  |  |  | 
| 230 |  |  |  |  |  |  | declare YearMonthDuration, | 
| 231 |  |  |  |  |  |  | with_facets [qw( pattern whiteSpace enumeration maxInclusiveDuration maxExclusiveDuration minInclusiveDuration minExclusiveDuration )], | 
| 232 |  |  |  |  |  |  | as Duration->parameterize(pattern => qr{\A[^DT]*\z}i); | 
| 233 |  |  |  |  |  |  |  | 
| 234 |  |  |  |  |  |  | declare DayTimeDuration, | 
| 235 |  |  |  |  |  |  | with_facets [qw( pattern whiteSpace enumeration maxInclusiveDuration maxExclusiveDuration minInclusiveDuration minExclusiveDuration )], | 
| 236 |  |  |  |  |  |  | as Duration->parameterize(pattern => qr{\A[^YM]*[DT].*\z}i); | 
| 237 |  |  |  |  |  |  |  | 
| 238 |  |  |  |  |  |  | dt_maker( | 
| 239 |  |  |  |  |  |  | DateTime => qr{\A | 
| 240 |  |  |  |  |  |  | (-?[0-9]{4,}) | 
| 241 |  |  |  |  |  |  | - | 
| 242 |  |  |  |  |  |  | ([0-9]{2}) | 
| 243 |  |  |  |  |  |  | - | 
| 244 |  |  |  |  |  |  | ([0-9]{2}) | 
| 245 |  |  |  |  |  |  | T | 
| 246 |  |  |  |  |  |  | ([0-9]{2}) | 
| 247 |  |  |  |  |  |  | : | 
| 248 |  |  |  |  |  |  | ([0-9]{2}) | 
| 249 |  |  |  |  |  |  | : | 
| 250 |  |  |  |  |  |  | ([0-9]{2}(?:\.[0-9]+)?) | 
| 251 |  |  |  |  |  |  | (Z | (?: [+-]\d{2}:?\d{2} ))? | 
| 252 |  |  |  |  |  |  | \z}xism, | 
| 253 |  |  |  |  |  |  | qw( year month day hour minute second time_zone ), | 
| 254 |  |  |  |  |  |  | ); | 
| 255 |  |  |  |  |  |  |  | 
| 256 |  |  |  |  |  |  | dt_maker( | 
| 257 |  |  |  |  |  |  | DateTimeStamp => qr{\A | 
| 258 |  |  |  |  |  |  | (-?[0-9]{4,}) | 
| 259 |  |  |  |  |  |  | - | 
| 260 |  |  |  |  |  |  | ([0-9]{2}) | 
| 261 |  |  |  |  |  |  | - | 
| 262 |  |  |  |  |  |  | ([0-9]{2}) | 
| 263 |  |  |  |  |  |  | T | 
| 264 |  |  |  |  |  |  | ([0-9]{2}) | 
| 265 |  |  |  |  |  |  | : | 
| 266 |  |  |  |  |  |  | ([0-9]{2}) | 
| 267 |  |  |  |  |  |  | : | 
| 268 |  |  |  |  |  |  | ([0-9]{2}(?:\.[0-9]+)?) | 
| 269 |  |  |  |  |  |  | (Z | (?: [+-]\d{2}:?\d{2} )) | 
| 270 |  |  |  |  |  |  | \z}xism, | 
| 271 |  |  |  |  |  |  | qw( year month day hour minute second time_zone ), | 
| 272 |  |  |  |  |  |  | ); | 
| 273 |  |  |  |  |  |  |  | 
| 274 |  |  |  |  |  |  | dt_maker( | 
| 275 |  |  |  |  |  |  | Time => qr{\A | 
| 276 |  |  |  |  |  |  | ([0-9]{2}) | 
| 277 |  |  |  |  |  |  | : | 
| 278 |  |  |  |  |  |  | ([0-9]{2}) | 
| 279 |  |  |  |  |  |  | : | 
| 280 |  |  |  |  |  |  | ([0-9]{2}(?:\.[0-9]+)?) | 
| 281 |  |  |  |  |  |  | (Z | (?: [+-]\d{2}:?\d{2} ))? | 
| 282 |  |  |  |  |  |  | \z}xism, | 
| 283 |  |  |  |  |  |  | qw( hour minute second time_zone ), | 
| 284 |  |  |  |  |  |  | ); | 
| 285 |  |  |  |  |  |  |  | 
| 286 |  |  |  |  |  |  | dt_maker( | 
| 287 |  |  |  |  |  |  | Date => qr{\A | 
| 288 |  |  |  |  |  |  | (-?[0-9]{4,}) | 
| 289 |  |  |  |  |  |  | - | 
| 290 |  |  |  |  |  |  | ([0-9]{2}) | 
| 291 |  |  |  |  |  |  | - | 
| 292 |  |  |  |  |  |  | ([0-9]{2}) | 
| 293 |  |  |  |  |  |  | (Z | (?: [+-]\d{2}:?\d{2} ))? | 
| 294 |  |  |  |  |  |  | \z}xism, | 
| 295 |  |  |  |  |  |  | qw( year month day time_zone ), | 
| 296 |  |  |  |  |  |  | ); | 
| 297 |  |  |  |  |  |  |  | 
| 298 |  |  |  |  |  |  | dt_maker( | 
| 299 |  |  |  |  |  |  | GYearMonth => qr{\A | 
| 300 |  |  |  |  |  |  | (-?[0-9]{4,}) | 
| 301 |  |  |  |  |  |  | - | 
| 302 |  |  |  |  |  |  | ([0-9]{2}) | 
| 303 |  |  |  |  |  |  | (Z | (?: [+-]\d{2}:?\d{2} ))? | 
| 304 |  |  |  |  |  |  | \z}xism, | 
| 305 |  |  |  |  |  |  | qw( year month time_zone ), | 
| 306 |  |  |  |  |  |  | ); | 
| 307 |  |  |  |  |  |  |  | 
| 308 |  |  |  |  |  |  | dt_maker( | 
| 309 |  |  |  |  |  |  | GYear => qr{\A | 
| 310 |  |  |  |  |  |  | (-?[0-9]{4,}) | 
| 311 |  |  |  |  |  |  | (Z | (?: [+-]\d{2}:?\d{2} ))? | 
| 312 |  |  |  |  |  |  | \z}xism, | 
| 313 |  |  |  |  |  |  | qw( year time_zone ), | 
| 314 |  |  |  |  |  |  | ); | 
| 315 |  |  |  |  |  |  |  | 
| 316 |  |  |  |  |  |  | dt_maker( | 
| 317 |  |  |  |  |  |  | GMonthDay => qr{\A | 
| 318 |  |  |  |  |  |  | - | 
| 319 |  |  |  |  |  |  | - | 
| 320 |  |  |  |  |  |  | ([0-9]{2}) | 
| 321 |  |  |  |  |  |  | - | 
| 322 |  |  |  |  |  |  | ([0-9]{2}) | 
| 323 |  |  |  |  |  |  | (Z | (?: [+-]\d{2}:?\d{2} ))? | 
| 324 |  |  |  |  |  |  | \z}xism, | 
| 325 |  |  |  |  |  |  | qw( month day time_zone ), | 
| 326 |  |  |  |  |  |  | ); | 
| 327 |  |  |  |  |  |  |  | 
| 328 |  |  |  |  |  |  | dt_maker( | 
| 329 |  |  |  |  |  |  | GDay => qr{\A | 
| 330 |  |  |  |  |  |  | - | 
| 331 |  |  |  |  |  |  | - | 
| 332 |  |  |  |  |  |  | - | 
| 333 |  |  |  |  |  |  | ([0-9]{2}) | 
| 334 |  |  |  |  |  |  | (Z | (?: [+-]\d{2}:?\d{2} ))? | 
| 335 |  |  |  |  |  |  | \z}xism, | 
| 336 |  |  |  |  |  |  | qw( day time_zone ), | 
| 337 |  |  |  |  |  |  | ); | 
| 338 |  |  |  |  |  |  |  | 
| 339 |  |  |  |  |  |  | dt_maker( | 
| 340 |  |  |  |  |  |  | GMonth => qr{\A | 
| 341 |  |  |  |  |  |  | - | 
| 342 |  |  |  |  |  |  | - | 
| 343 |  |  |  |  |  |  | ([0-9]{2}) | 
| 344 |  |  |  |  |  |  | (Z | (?: [+-]\d{2}:?\d{2} ))? | 
| 345 |  |  |  |  |  |  | \z}xism, | 
| 346 |  |  |  |  |  |  | qw( month time_zone ), | 
| 347 |  |  |  |  |  |  | ); | 
| 348 |  |  |  |  |  |  |  | 
| 349 |  |  |  |  |  |  | __PACKAGE__->meta->make_immutable; | 
| 350 |  |  |  |  |  |  |  | 
| 351 |  |  |  |  |  |  |  | 
| 352 |  |  |  |  |  |  | =pod | 
| 353 |  |  |  |  |  |  |  | 
| 354 |  |  |  |  |  |  | =encoding utf-8 | 
| 355 |  |  |  |  |  |  |  | 
| 356 |  |  |  |  |  |  | =head1 NAME | 
| 357 |  |  |  |  |  |  |  | 
| 358 |  |  |  |  |  |  | Types::XSD - type constraints based on XML schema datatypes | 
| 359 |  |  |  |  |  |  |  | 
| 360 |  |  |  |  |  |  | =head1 SYNOPSIS | 
| 361 |  |  |  |  |  |  |  | 
| 362 |  |  |  |  |  |  | package Person; | 
| 363 |  |  |  |  |  |  |  | 
| 364 |  |  |  |  |  |  | use Moo; | 
| 365 |  |  |  |  |  |  | use Types::XSD qw( PositiveInteger String ); | 
| 366 |  |  |  |  |  |  |  | 
| 367 |  |  |  |  |  |  | has name => (is => "ro", isa => String[ minLength => 1 ]); | 
| 368 |  |  |  |  |  |  | has age  => (is => "ro", isa => PositiveInteger); | 
| 369 |  |  |  |  |  |  |  | 
| 370 |  |  |  |  |  |  | =head1 DESCRIPTION | 
| 371 |  |  |  |  |  |  |  | 
| 372 |  |  |  |  |  |  | Types::XSD is a type constraint library inspired by XML Schema, and built | 
| 373 |  |  |  |  |  |  | with L<Type::Library>. It can be used as a type constraint library for | 
| 374 |  |  |  |  |  |  | L<Moo>, L<Mouse> or L<Moose>, or used completely independently of any OO | 
| 375 |  |  |  |  |  |  | framework. | 
| 376 |  |  |  |  |  |  |  | 
| 377 |  |  |  |  |  |  | This module is an extension of L<Types::XSD::Lite> (which has fewer type | 
| 378 |  |  |  |  |  |  | constraints, but fewer dependencies). For completeness, the type constraints | 
| 379 |  |  |  |  |  |  | and other features inherited from Types::XSD::Lite are documented below | 
| 380 |  |  |  |  |  |  | too. | 
| 381 |  |  |  |  |  |  |  | 
| 382 |  |  |  |  |  |  | =head2 Type Constraints | 
| 383 |  |  |  |  |  |  |  | 
| 384 |  |  |  |  |  |  | This module defines the following type constraints based on the data types | 
| 385 |  |  |  |  |  |  | defined in L<XML Schema|http://www.w3.org/TR/xmlschema-2/>. (The names of | 
| 386 |  |  |  |  |  |  | the type constraints are the same as the XML Schema data types, but | 
| 387 |  |  |  |  |  |  | capitalization often differs.) | 
| 388 |  |  |  |  |  |  |  | 
| 389 |  |  |  |  |  |  | I've added some quick explainations of what each type is, but for details, | 
| 390 |  |  |  |  |  |  | see the XML Schema specification. | 
| 391 |  |  |  |  |  |  |  | 
| 392 |  |  |  |  |  |  | =over | 
| 393 |  |  |  |  |  |  |  | 
| 394 |  |  |  |  |  |  | =item C<< AnyType >> | 
| 395 |  |  |  |  |  |  |  | 
| 396 |  |  |  |  |  |  | As per C<Any> from L<Types::Standard>. | 
| 397 |  |  |  |  |  |  |  | 
| 398 |  |  |  |  |  |  | =item C<< AnySimpleType >> | 
| 399 |  |  |  |  |  |  |  | 
| 400 |  |  |  |  |  |  | As per C<Value> from L<Types::Standard>. | 
| 401 |  |  |  |  |  |  |  | 
| 402 |  |  |  |  |  |  | =item C<< String >> | 
| 403 |  |  |  |  |  |  |  | 
| 404 |  |  |  |  |  |  | As per C<Str> from L<Types::Standard>. | 
| 405 |  |  |  |  |  |  |  | 
| 406 |  |  |  |  |  |  | =item C<< NormalizedString >> | 
| 407 |  |  |  |  |  |  |  | 
| 408 |  |  |  |  |  |  | A string containing no line breaks, carriage returns or tabs. | 
| 409 |  |  |  |  |  |  |  | 
| 410 |  |  |  |  |  |  | =item C<< Token >> | 
| 411 |  |  |  |  |  |  |  | 
| 412 |  |  |  |  |  |  | Like C<NormalizedString>, but also no leading or trailing space, and no | 
| 413 |  |  |  |  |  |  | doubled spaces (i.e. not C<< /\s{2,}/ >>). | 
| 414 |  |  |  |  |  |  |  | 
| 415 |  |  |  |  |  |  | =item C<< Language >> | 
| 416 |  |  |  |  |  |  |  | 
| 417 |  |  |  |  |  |  | An RFC 3066 language code. | 
| 418 |  |  |  |  |  |  |  | 
| 419 |  |  |  |  |  |  | =item C<< Name >> | 
| 420 |  |  |  |  |  |  |  | 
| 421 |  |  |  |  |  |  | Something that could be a valid XML element or attribute name. These roughly | 
| 422 |  |  |  |  |  |  | correspond to Perl identifiers but may also contain colons, hyphens and stops. | 
| 423 |  |  |  |  |  |  | (Digits, hyphens and stops are not allowed as the first character.) | 
| 424 |  |  |  |  |  |  |  | 
| 425 |  |  |  |  |  |  | =item C<< NmToken >> | 
| 426 |  |  |  |  |  |  |  | 
| 427 |  |  |  |  |  |  | Slightly looser version of C<Name>; allows digits, hyphens and stops in the | 
| 428 |  |  |  |  |  |  | first character. | 
| 429 |  |  |  |  |  |  |  | 
| 430 |  |  |  |  |  |  | =item C<< NmTokens >> | 
| 431 |  |  |  |  |  |  |  | 
| 432 |  |  |  |  |  |  | Space-separated list of C<NmToken>. | 
| 433 |  |  |  |  |  |  |  | 
| 434 |  |  |  |  |  |  | =item C<< NCName >> | 
| 435 |  |  |  |  |  |  |  | 
| 436 |  |  |  |  |  |  | Slightly tighter vesion of C<Name>; disallows colons. | 
| 437 |  |  |  |  |  |  |  | 
| 438 |  |  |  |  |  |  | =item C<< Id >> | 
| 439 |  |  |  |  |  |  |  | 
| 440 |  |  |  |  |  |  | Effectively the same as C<NCName>. | 
| 441 |  |  |  |  |  |  |  | 
| 442 |  |  |  |  |  |  | =item C<< IdRef >> | 
| 443 |  |  |  |  |  |  |  | 
| 444 |  |  |  |  |  |  | Effectively the same as C<NCName>. | 
| 445 |  |  |  |  |  |  |  | 
| 446 |  |  |  |  |  |  | =item C<< IdRefs >> | 
| 447 |  |  |  |  |  |  |  | 
| 448 |  |  |  |  |  |  | Space-separated list of C<IdRef>. | 
| 449 |  |  |  |  |  |  |  | 
| 450 |  |  |  |  |  |  | =item C<< Entity >> | 
| 451 |  |  |  |  |  |  |  | 
| 452 |  |  |  |  |  |  | Effectively the same as C<NCName>. | 
| 453 |  |  |  |  |  |  |  | 
| 454 |  |  |  |  |  |  | =item C<< Entities >> | 
| 455 |  |  |  |  |  |  |  | 
| 456 |  |  |  |  |  |  | Space-separated list of C<Entity>. | 
| 457 |  |  |  |  |  |  |  | 
| 458 |  |  |  |  |  |  | =item C<< Boolean >> | 
| 459 |  |  |  |  |  |  |  | 
| 460 |  |  |  |  |  |  | Allows C<< "true" >>, C<< "false" >>, C<< "1" >> and C<< "0" >> | 
| 461 |  |  |  |  |  |  | (case-insensitively). | 
| 462 |  |  |  |  |  |  |  | 
| 463 |  |  |  |  |  |  | Gotcha: The string C<< "false" >> evaluates to true in Perl. You probably | 
| 464 |  |  |  |  |  |  | want to use C<< Bool >> from L<Types::Standard> instead. | 
| 465 |  |  |  |  |  |  |  | 
| 466 |  |  |  |  |  |  | =item C<< Base64Binary >> | 
| 467 |  |  |  |  |  |  |  | 
| 468 |  |  |  |  |  |  | Strings which are valid Base64 data. Allows whitespace. | 
| 469 |  |  |  |  |  |  |  | 
| 470 |  |  |  |  |  |  | Gotcha: If you parameterize this with C<length>, C<maxLength> or C<minLength>, | 
| 471 |  |  |  |  |  |  | it is the length of the I<decoded> string which will be checked. | 
| 472 |  |  |  |  |  |  |  | 
| 473 |  |  |  |  |  |  | =item C<< HexBinary >> | 
| 474 |  |  |  |  |  |  |  | 
| 475 |  |  |  |  |  |  | Strings which are valid hexadecimal data. Disallows whitespace; disallows | 
| 476 |  |  |  |  |  |  | leading C<< 0x >>. | 
| 477 |  |  |  |  |  |  |  | 
| 478 |  |  |  |  |  |  | Gotcha: If you parameterize this with C<length>, C<maxLength> or C<minLength>, | 
| 479 |  |  |  |  |  |  | it is the length of the I<decoded> string which will be checked. | 
| 480 |  |  |  |  |  |  |  | 
| 481 |  |  |  |  |  |  | =item C<< Float >> | 
| 482 |  |  |  |  |  |  |  | 
| 483 |  |  |  |  |  |  | As per C<Num> from L<Types::Standard>. | 
| 484 |  |  |  |  |  |  |  | 
| 485 |  |  |  |  |  |  | =item C<< Double >> | 
| 486 |  |  |  |  |  |  |  | 
| 487 |  |  |  |  |  |  | As per C<Num> from L<Types::Standard>. | 
| 488 |  |  |  |  |  |  |  | 
| 489 |  |  |  |  |  |  | =item C<< AnyURI >> | 
| 490 |  |  |  |  |  |  |  | 
| 491 |  |  |  |  |  |  | Any absolute I<< or relative >> URI. Effectively, any string at all! | 
| 492 |  |  |  |  |  |  |  | 
| 493 |  |  |  |  |  |  | =item C<< QName >> | 
| 494 |  |  |  |  |  |  |  | 
| 495 |  |  |  |  |  |  | An XML QName; something that could be used as a valid element name in a | 
| 496 |  |  |  |  |  |  | namespaced XML document. | 
| 497 |  |  |  |  |  |  |  | 
| 498 |  |  |  |  |  |  | Gotcha: while C<length>, C<maxLength> and C<minLength> are allowed facets for | 
| 499 |  |  |  |  |  |  | parameterization, they are silently ignored, as per the specification! | 
| 500 |  |  |  |  |  |  |  | 
| 501 |  |  |  |  |  |  | =item C<< Notation >> | 
| 502 |  |  |  |  |  |  |  | 
| 503 |  |  |  |  |  |  | Effectively the same as C<QName>. According to XML Schema, this is I<always> | 
| 504 |  |  |  |  |  |  | supposed to be parameterized with an enumeration. But we don't enforce that. | 
| 505 |  |  |  |  |  |  |  | 
| 506 |  |  |  |  |  |  | Gotcha: while C<length>, C<maxLength> and C<minLength> are allowed facets for | 
| 507 |  |  |  |  |  |  | parameterization, they are silently ignored, as per the specification! | 
| 508 |  |  |  |  |  |  |  | 
| 509 |  |  |  |  |  |  | =item C<< Decimal >> | 
| 510 |  |  |  |  |  |  |  | 
| 511 |  |  |  |  |  |  | Numbers possibly including a decimal point, but not allowing exponential | 
| 512 |  |  |  |  |  |  | notation (e.g. C<< "3.14e-3" >>). | 
| 513 |  |  |  |  |  |  |  | 
| 514 |  |  |  |  |  |  | =item C<< Integer >> | 
| 515 |  |  |  |  |  |  |  | 
| 516 |  |  |  |  |  |  | As per C<Int> from L<Types::Standard>. | 
| 517 |  |  |  |  |  |  |  | 
| 518 |  |  |  |  |  |  | =item C<< NonPositiveInteger >> | 
| 519 |  |  |  |  |  |  |  | 
| 520 |  |  |  |  |  |  | An C<Integer> 0 or below. | 
| 521 |  |  |  |  |  |  |  | 
| 522 |  |  |  |  |  |  | =item C<< NegativeInteger >> | 
| 523 |  |  |  |  |  |  |  | 
| 524 |  |  |  |  |  |  | An C<Integer> -1 or below. | 
| 525 |  |  |  |  |  |  |  | 
| 526 |  |  |  |  |  |  | =item C<< Long >> | 
| 527 |  |  |  |  |  |  |  | 
| 528 |  |  |  |  |  |  | An C<Integer> between -9223372036854775808 and 9223372036854775807 (inclusive). | 
| 529 |  |  |  |  |  |  |  | 
| 530 |  |  |  |  |  |  | =item C<< Int >> | 
| 531 |  |  |  |  |  |  |  | 
| 532 |  |  |  |  |  |  | An C<Integer> between -2147483648 and 2147483647 (inclusive). | 
| 533 |  |  |  |  |  |  |  | 
| 534 |  |  |  |  |  |  | =item C<< Short >> | 
| 535 |  |  |  |  |  |  |  | 
| 536 |  |  |  |  |  |  | An C<Integer> between -32768 and 32767 (inclusive). | 
| 537 |  |  |  |  |  |  |  | 
| 538 |  |  |  |  |  |  | =item C<< Byte >> | 
| 539 |  |  |  |  |  |  |  | 
| 540 |  |  |  |  |  |  | An C<Integer> between -128 and 127 (inclusive). | 
| 541 |  |  |  |  |  |  |  | 
| 542 |  |  |  |  |  |  | =item C<< NonNegativeInteger >> | 
| 543 |  |  |  |  |  |  |  | 
| 544 |  |  |  |  |  |  | An C<Integer> 0 or above. | 
| 545 |  |  |  |  |  |  |  | 
| 546 |  |  |  |  |  |  | =item C<< PositiveInteger >> | 
| 547 |  |  |  |  |  |  |  | 
| 548 |  |  |  |  |  |  | An C<Integer> 1 or above. | 
| 549 |  |  |  |  |  |  |  | 
| 550 |  |  |  |  |  |  | =item C<< UnsignedLong >> | 
| 551 |  |  |  |  |  |  |  | 
| 552 |  |  |  |  |  |  | A C<NonNegativeInteger> between 0 and 18446744073709551615 (inclusive). | 
| 553 |  |  |  |  |  |  |  | 
| 554 |  |  |  |  |  |  | =item C<< UnsignedInt >> | 
| 555 |  |  |  |  |  |  |  | 
| 556 |  |  |  |  |  |  | A C<NonNegativeInteger> between 0 and 4294967295 (inclusive). | 
| 557 |  |  |  |  |  |  |  | 
| 558 |  |  |  |  |  |  | =item C<< UnsignedShort >> | 
| 559 |  |  |  |  |  |  |  | 
| 560 |  |  |  |  |  |  | A C<NonNegativeInteger> between 0 and 65535 (inclusive). | 
| 561 |  |  |  |  |  |  |  | 
| 562 |  |  |  |  |  |  | =item C<< UnsignedByte >> | 
| 563 |  |  |  |  |  |  |  | 
| 564 |  |  |  |  |  |  | A C<NonNegativeInteger> between 0 and 255 (inclusive). | 
| 565 |  |  |  |  |  |  |  | 
| 566 |  |  |  |  |  |  | =item C<< Duration >> | 
| 567 |  |  |  |  |  |  |  | 
| 568 |  |  |  |  |  |  | An ISO 8601 duration. | 
| 569 |  |  |  |  |  |  |  | 
| 570 |  |  |  |  |  |  | =item C<< YearMonthDuration >> | 
| 571 |  |  |  |  |  |  |  | 
| 572 |  |  |  |  |  |  | An ISO 8601 duration restricted to cover only years and months. | 
| 573 |  |  |  |  |  |  |  | 
| 574 |  |  |  |  |  |  | =item C<< DayTimeDuration >> | 
| 575 |  |  |  |  |  |  |  | 
| 576 |  |  |  |  |  |  | An ISO 8601 duration restricted to cover only days, hours, minutes and | 
| 577 |  |  |  |  |  |  | seconds. (Note that this still permits durations of many years, as the | 
| 578 |  |  |  |  |  |  | days component is an arbitrary non-negative integer.) | 
| 579 |  |  |  |  |  |  |  | 
| 580 |  |  |  |  |  |  | =item C<< DateTime >> | 
| 581 |  |  |  |  |  |  |  | 
| 582 |  |  |  |  |  |  | An ISO 8601 datetime with optional timezone. | 
| 583 |  |  |  |  |  |  |  | 
| 584 |  |  |  |  |  |  | =item C<< DateTimeStamp >> | 
| 585 |  |  |  |  |  |  |  | 
| 586 |  |  |  |  |  |  | An ISO 8601 datetime with required timezone. | 
| 587 |  |  |  |  |  |  |  | 
| 588 |  |  |  |  |  |  | =item C<< Time >> | 
| 589 |  |  |  |  |  |  |  | 
| 590 |  |  |  |  |  |  | An ISO 8601 time with optional timezone. | 
| 591 |  |  |  |  |  |  |  | 
| 592 |  |  |  |  |  |  | =item C<< Date >> | 
| 593 |  |  |  |  |  |  |  | 
| 594 |  |  |  |  |  |  | An ISO 8601 date with optional timezone. | 
| 595 |  |  |  |  |  |  |  | 
| 596 |  |  |  |  |  |  | =item C<< GYearMonth >> | 
| 597 |  |  |  |  |  |  |  | 
| 598 |  |  |  |  |  |  | An year-month pair with optional timezone. | 
| 599 |  |  |  |  |  |  |  | 
| 600 |  |  |  |  |  |  | =item C<< GYear >> | 
| 601 |  |  |  |  |  |  |  | 
| 602 |  |  |  |  |  |  | An year with optional timezone. | 
| 603 |  |  |  |  |  |  |  | 
| 604 |  |  |  |  |  |  | =item C<< GMonthDay >> | 
| 605 |  |  |  |  |  |  |  | 
| 606 |  |  |  |  |  |  | An month-day pair with optional timezone. | 
| 607 |  |  |  |  |  |  |  | 
| 608 |  |  |  |  |  |  | =item C<< GDay >> | 
| 609 |  |  |  |  |  |  |  | 
| 610 |  |  |  |  |  |  | An day with optional timezone. | 
| 611 |  |  |  |  |  |  |  | 
| 612 |  |  |  |  |  |  | =item C<< GMonth >> | 
| 613 |  |  |  |  |  |  |  | 
| 614 |  |  |  |  |  |  | An month with optional timezone. | 
| 615 |  |  |  |  |  |  |  | 
| 616 |  |  |  |  |  |  | =back | 
| 617 |  |  |  |  |  |  |  | 
| 618 |  |  |  |  |  |  | =head2 Parameters | 
| 619 |  |  |  |  |  |  |  | 
| 620 |  |  |  |  |  |  | Datatypes can be parameterized using the facets defined by XML Schema. For | 
| 621 |  |  |  |  |  |  | example: | 
| 622 |  |  |  |  |  |  |  | 
| 623 |  |  |  |  |  |  | use Types::XSD qw( String Decimal PositiveInteger Token ); | 
| 624 |  |  |  |  |  |  |  | 
| 625 |  |  |  |  |  |  | my @sizes = qw( XS S M L XL XXL ); | 
| 626 |  |  |  |  |  |  |  | 
| 627 |  |  |  |  |  |  | has name   => (is => "ro", isa => String[ minLength => 1 ]); | 
| 628 |  |  |  |  |  |  | has price  => (is => "ro", isa => Decimal[ fractionDigits => 2 ]); | 
| 629 |  |  |  |  |  |  | has rating => (is => "ro", isa => PositiveInteger[ maxInclusive => 5 ]); | 
| 630 |  |  |  |  |  |  | has size   => (is => "ro", isa => Token[ enumeration => \@sizes ]); | 
| 631 |  |  |  |  |  |  |  | 
| 632 |  |  |  |  |  |  | The following facets exist, but not all facets are supported for all | 
| 633 |  |  |  |  |  |  | datatypes. (The module will croak if you try to use an unsupported facet.) | 
| 634 |  |  |  |  |  |  |  | 
| 635 |  |  |  |  |  |  | =over | 
| 636 |  |  |  |  |  |  |  | 
| 637 |  |  |  |  |  |  | =item C<< enumeration >> | 
| 638 |  |  |  |  |  |  |  | 
| 639 |  |  |  |  |  |  | An arrayref of allowable values. You should probably use L<Type::Tiny::Enum> | 
| 640 |  |  |  |  |  |  | instead. | 
| 641 |  |  |  |  |  |  |  | 
| 642 |  |  |  |  |  |  | =item C<< pattern >> | 
| 643 |  |  |  |  |  |  |  | 
| 644 |  |  |  |  |  |  | A regular expression that the value is expected to conform to. Use a normal | 
| 645 |  |  |  |  |  |  | Perl quoted regexp: | 
| 646 |  |  |  |  |  |  |  | 
| 647 |  |  |  |  |  |  | Token[ pattern => qr{^[a-z]+$} ] | 
| 648 |  |  |  |  |  |  |  | 
| 649 |  |  |  |  |  |  | =item C<< whiteSpace >> | 
| 650 |  |  |  |  |  |  |  | 
| 651 |  |  |  |  |  |  | The C<whiteSpace> facet is ignored as I'm not entirely sure what it should | 
| 652 |  |  |  |  |  |  | do. It perhaps makes sense for coercions, but this module doesn't define any | 
| 653 |  |  |  |  |  |  | coercions. | 
| 654 |  |  |  |  |  |  |  | 
| 655 |  |  |  |  |  |  | =item C<< assertions >> | 
| 656 |  |  |  |  |  |  |  | 
| 657 |  |  |  |  |  |  | An arrayref of arbitrary additional restrictions, expressed as strings of | 
| 658 |  |  |  |  |  |  | Perl code or coderefs operating on C<< $_ >>. | 
| 659 |  |  |  |  |  |  |  | 
| 660 |  |  |  |  |  |  | For example: | 
| 661 |  |  |  |  |  |  |  | 
| 662 |  |  |  |  |  |  | Integer[ | 
| 663 |  |  |  |  |  |  | assertions => [ | 
| 664 |  |  |  |  |  |  | '$_ % 3 == 0',            # multiple of three, and... | 
| 665 |  |  |  |  |  |  | sub { is_nice($_) },      # is nice (whatever that means) | 
| 666 |  |  |  |  |  |  | ], | 
| 667 |  |  |  |  |  |  | ], | 
| 668 |  |  |  |  |  |  |  | 
| 669 |  |  |  |  |  |  | Strings of Perl code will result in faster-running type constraints. | 
| 670 |  |  |  |  |  |  |  | 
| 671 |  |  |  |  |  |  | =item C<< length >>, C<< maxLength >>, C<< minLength >> | 
| 672 |  |  |  |  |  |  |  | 
| 673 |  |  |  |  |  |  | Restrict the length of a value. For example C<< Integer[length=>2] >> allows | 
| 674 |  |  |  |  |  |  | C<10>, C<99> and C<-1>, but not C<100>, C<9> or C<-10>. | 
| 675 |  |  |  |  |  |  |  | 
| 676 |  |  |  |  |  |  | Types::XSD won't prevent you from making ridiculous constraints such as | 
| 677 |  |  |  |  |  |  | C<< String[ maxLength => 1, minLength => 2 ] >>. | 
| 678 |  |  |  |  |  |  |  | 
| 679 |  |  |  |  |  |  | Note that on C<HexBinary> and C<Base64Binary> types, the lengths apply to | 
| 680 |  |  |  |  |  |  | the decoded string. Length restrictions are silently ignored for C<QName> | 
| 681 |  |  |  |  |  |  | and C<Notation> because the W3C doesn't think you should care what length | 
| 682 |  |  |  |  |  |  | these datatypes are. | 
| 683 |  |  |  |  |  |  |  | 
| 684 |  |  |  |  |  |  | =item C<< maxInclusive >>, C<< minInclusive >>, C<< maxExclusive >>, C<< minExclusive >> | 
| 685 |  |  |  |  |  |  |  | 
| 686 |  |  |  |  |  |  | Supported for numeric types and datetime/duration-related types. | 
| 687 |  |  |  |  |  |  |  | 
| 688 |  |  |  |  |  |  | Note that to be super-correct, the C<< {max,min}{Inclusive,Exclusive} >> | 
| 689 |  |  |  |  |  |  | facets for numeric types are performed by passing the numbers through | 
| 690 |  |  |  |  |  |  | L<Math::BigInt> or L<Math::BigFloat>, so may be a little slow. | 
| 691 |  |  |  |  |  |  |  | 
| 692 |  |  |  |  |  |  | =item C<< totalDigits >> | 
| 693 |  |  |  |  |  |  |  | 
| 694 |  |  |  |  |  |  | For a decimal (or type derived from decimals) specifies that the total number | 
| 695 |  |  |  |  |  |  | of digits for the value must be at most this number. Given | 
| 696 |  |  |  |  |  |  | C<< Decimal[ totalDigits => 3 ] >>, C<1.23>, C<12.3>, C<123>, C<1.2> and C<1> | 
| 697 |  |  |  |  |  |  | are all allowable; C<1.234> is not. C<1.230> is also not, but this may change | 
| 698 |  |  |  |  |  |  | in a future version. | 
| 699 |  |  |  |  |  |  |  | 
| 700 |  |  |  |  |  |  | =item C<< fractionDigits >> | 
| 701 |  |  |  |  |  |  |  | 
| 702 |  |  |  |  |  |  | Like C<totalDigits> but ignores digits before the decimal point. | 
| 703 |  |  |  |  |  |  |  | 
| 704 |  |  |  |  |  |  | =item C<< explicitTimezone >> | 
| 705 |  |  |  |  |  |  |  | 
| 706 |  |  |  |  |  |  | May be C<< "optional" >>, C<< "prohibited" >> or C<< "required" >>. For | 
| 707 |  |  |  |  |  |  | example: | 
| 708 |  |  |  |  |  |  |  | 
| 709 |  |  |  |  |  |  | Time[ explicitTimezone => "prohibited" ] | 
| 710 |  |  |  |  |  |  |  | 
| 711 |  |  |  |  |  |  | =back | 
| 712 |  |  |  |  |  |  |  | 
| 713 |  |  |  |  |  |  | =head2 Functions | 
| 714 |  |  |  |  |  |  |  | 
| 715 |  |  |  |  |  |  | This module also exports some convenience functions: | 
| 716 |  |  |  |  |  |  |  | 
| 717 |  |  |  |  |  |  | =over | 
| 718 |  |  |  |  |  |  |  | 
| 719 |  |  |  |  |  |  | =item C<< dur_parse($str) >> | 
| 720 |  |  |  |  |  |  |  | 
| 721 |  |  |  |  |  |  | Parse an xsd:duration string, returning a L<DateTime::Duration>. | 
| 722 |  |  |  |  |  |  |  | 
| 723 |  |  |  |  |  |  | =item C<< dur_cmp($a, $b) >> | 
| 724 |  |  |  |  |  |  |  | 
| 725 |  |  |  |  |  |  | Compare two strings conforming to the xsd:duration datatype to indicate | 
| 726 |  |  |  |  |  |  | which is the longer duration. | 
| 727 |  |  |  |  |  |  |  | 
| 728 |  |  |  |  |  |  | Returns -1 if $a is shorter. Returns 1 if $b is shorter. Returns 0 if the | 
| 729 |  |  |  |  |  |  | durations are identical. Returns undef if the comparison is indeterminate; | 
| 730 |  |  |  |  |  |  | for example, "P1Y" (one year) and "P365D" (365 days) are not necessarily | 
| 731 |  |  |  |  |  |  | identical - in leap years "P365D" is shorter. | 
| 732 |  |  |  |  |  |  |  | 
| 733 |  |  |  |  |  |  | =item C<< dt_cmp($type, $a, $b) >> | 
| 734 |  |  |  |  |  |  |  | 
| 735 |  |  |  |  |  |  | Compare two datetime-like strings. For example, two C<gYearMonth> strings | 
| 736 |  |  |  |  |  |  | can be compared using: | 
| 737 |  |  |  |  |  |  |  | 
| 738 |  |  |  |  |  |  | dt_cmp(GYearMonth, "2009-02", "2010-10"); | 
| 739 |  |  |  |  |  |  |  | 
| 740 |  |  |  |  |  |  | Both strings are expected to conform to the same datatype. It doesn't make | 
| 741 |  |  |  |  |  |  | much sense to compare them otherwise. | 
| 742 |  |  |  |  |  |  |  | 
| 743 |  |  |  |  |  |  | =item C<< dt_parse($type, $str) >> | 
| 744 |  |  |  |  |  |  |  | 
| 745 |  |  |  |  |  |  | Parse a datetime-like string, returning a L<DateTime::Incomplete> object. | 
| 746 |  |  |  |  |  |  | Note that L<DateTime::Incomplete> objects are always returned, even if the | 
| 747 |  |  |  |  |  |  | datetime is potentially complete. | 
| 748 |  |  |  |  |  |  |  | 
| 749 |  |  |  |  |  |  | =back | 
| 750 |  |  |  |  |  |  |  | 
| 751 |  |  |  |  |  |  | =head1 BUGS | 
| 752 |  |  |  |  |  |  |  | 
| 753 |  |  |  |  |  |  | Please report any bugs to | 
| 754 |  |  |  |  |  |  | L<http://rt.cpan.org/Dist/Display.html?Queue=Types-XSD>. | 
| 755 |  |  |  |  |  |  |  | 
| 756 |  |  |  |  |  |  | =head1 SEE ALSO | 
| 757 |  |  |  |  |  |  |  | 
| 758 |  |  |  |  |  |  | L<Type::Tiny>, L<Types::XSD::Lite>, L<Types::Standard>. | 
| 759 |  |  |  |  |  |  |  | 
| 760 |  |  |  |  |  |  | =over | 
| 761 |  |  |  |  |  |  |  | 
| 762 |  |  |  |  |  |  | =item * | 
| 763 |  |  |  |  |  |  |  | 
| 764 |  |  |  |  |  |  | L<http://www.w3.org/TR/xmlschema-2/> Datatypes in XML Schema 1.0 | 
| 765 |  |  |  |  |  |  |  | 
| 766 |  |  |  |  |  |  | =item * | 
| 767 |  |  |  |  |  |  |  | 
| 768 |  |  |  |  |  |  | L<http://www.w3.org/TR/xmlschema11-2/> Datatypes in XML Schema 1.1 | 
| 769 |  |  |  |  |  |  |  | 
| 770 |  |  |  |  |  |  | =back | 
| 771 |  |  |  |  |  |  |  | 
| 772 |  |  |  |  |  |  | =head1 AUTHOR | 
| 773 |  |  |  |  |  |  |  | 
| 774 |  |  |  |  |  |  | Toby Inkster E<lt>tobyink@cpan.orgE<gt>. | 
| 775 |  |  |  |  |  |  |  | 
| 776 |  |  |  |  |  |  | =head1 COPYRIGHT AND LICENCE | 
| 777 |  |  |  |  |  |  |  | 
| 778 |  |  |  |  |  |  | This software is copyright (c) 2013-2014, 2021 by Toby Inkster. | 
| 779 |  |  |  |  |  |  |  | 
| 780 |  |  |  |  |  |  | This is free software; you can redistribute it and/or modify it under | 
| 781 |  |  |  |  |  |  | the same terms as the Perl 5 programming language system itself. | 
| 782 |  |  |  |  |  |  |  | 
| 783 |  |  |  |  |  |  | =head1 DISCLAIMER OF WARRANTIES | 
| 784 |  |  |  |  |  |  |  | 
| 785 |  |  |  |  |  |  | THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED | 
| 786 |  |  |  |  |  |  | WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF | 
| 787 |  |  |  |  |  |  | MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. | 
| 788 |  |  |  |  |  |  |  |