File Coverage

blib/lib/TypeLibrary/FromXSD.pm
Criterion Covered Total %
statement 13 15 86.6
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 18 20 90.0


line stmt bran cond sub pod time code
1             package TypeLibrary::FromXSD;
2              
3             # ABSTRACT: create a Type::Tiny library of simpleTypes in .xsd files.
4              
5 1     1   76486 use strict;
  1         3  
  1         37  
6 1     1   5 use warnings;
  1         2  
  1         26  
7              
8 1     1   1023 use Moo;
  1         19102  
  1         6  
9              
10 1     1   1928 use File::Basename;
  1         2  
  1         83  
11 1     1   2193 use XML::LibXML;
  0            
  0            
12              
13             use TypeLibrary::FromXSD::Element;
14              
15             our $VERSION = 0.03;
16              
17             has types => (is => 'rwp');
18             has xsd => (is => 'ro', required => 1);
19             has output => (is => 'ro');
20             has namespace => (is => 'ro');
21             has version_add => (is => 'ro', default => sub{ '0.01' } );
22              
23             sub run {
24             my ($self) = @_;
25              
26             my $tree = XML::LibXML->new->parse_file( $self->xsd )->getDocumentElement;
27             my @typeNodes = $tree->getElementsByTagName('xs:simpleType');
28              
29             my $out_fh = *STDOUT;
30             my $namespace = $self->namespace || 'Library';
31              
32             if ( $self->output ) {
33             open $out_fh, '>', $self->output;
34             $namespace = $self->namespace || basename $self->output;
35             $namespace =~ s/\.pm\z//;
36             }
37              
38             my @types;
39             my %types_used;
40             for my $node ( @typeNodes ) {
41             my $element = TypeLibrary::FromXSD::Element->new(
42             $node,
43             validate => {
44             date => 'validate_date',
45             dateTime => 'validate_datetime',
46             },
47             );
48              
49             push @types, $element;
50             $types_used{ $element->orig_base }++;
51             }
52              
53             my $declare = join ' ', map{ $_->name }@types;
54             print $out_fh $self->_module_header( $namespace, $declare );
55            
56             if ( $types_used{date} || $types_used{dateTime} ) {
57             print $out_fh "\nuse DateTime;\n\n";
58             }
59              
60             for my $type ( @types ) {
61             print $out_fh $type->type,"\n\n";
62             }
63              
64             if ( $types_used{date} ) {
65             print $out_fh $self->_validate_date_sub;
66             }
67              
68             if ( $types_used{dateTime} ) {
69             print $out_fh $self->_validate_datetime_sub;
70             }
71              
72             print $out_fh "1;\n";
73             }
74              
75             sub _module_header {
76             my ($self, $ns, $declare) = @_;
77              
78             my $version = $self->version_add;
79             if ( $self->output and -f $self->output ) {
80             my $content = do{ local (@ARGV,$/) = $self->output; <> };
81             ($version) = $content =~ m{\$VERSION\s*=\s*(.*?);};
82             $version += $self->version_add;
83             }
84              
85             qq*package $ns;
86              
87             use strict;
88             use warnings;
89              
90             use Type::Library
91             -base,
92             -declare => qw( $declare );
93             use Type::Utils -all;
94             use Types::Standard -types;
95              
96             our \$VERSION = $version;
97             *;
98             }
99              
100             sub _validate_date_sub {
101             q*sub validate_date {
102             my ($date) = @_;
103              
104             $date =~ s/\A-//;
105             my ($year,$month,$day,$hour,$min) = split /[-Z+:]/, $date;
106              
107             eval {
108             DateTime->new(
109             year => $year,
110             month => $month,
111             day => $day,
112             );
113             } or return 0;
114              
115             return 0 if ( $hour and ( $hour < 0 or $hour > 12 ) );
116             return 0 if ( $min and ( $min < 0 or $min > 59 ) );
117              
118             return 1;
119             }
120              
121             *;
122             }
123              
124             sub _validate_datetime_sub {
125             q*sub validate_datetime {
126             my ($date) = @_;
127              
128             $date =~ s/\A-//;
129             my ($year,$month,$day,$hour,$min) = split /[-Z+:]/, $date;
130              
131             eval {
132             DateTime->new(
133             year => $year,
134             month => $month,
135             day => $day,
136             );
137             } or return 0;
138              
139             return 0 if ( $hour and ( $hour < 0 or $hour > 12 ) );
140             return 0 if ( $min and ( $min < 0 or $min > 59 ) );
141              
142             return 1;
143             }
144              
145             *;
146             }
147              
148             1;
149              
150             __END__