diff options
Diffstat (limited to 'perllib/Open311/Endpoint/Schema.pm')
-rw-r--r-- | perllib/Open311/Endpoint/Schema.pm | 174 |
1 files changed, 174 insertions, 0 deletions
diff --git a/perllib/Open311/Endpoint/Schema.pm b/perllib/Open311/Endpoint/Schema.pm new file mode 100644 index 000000000..e30f9ad90 --- /dev/null +++ b/perllib/Open311/Endpoint/Schema.pm @@ -0,0 +1,174 @@ +package Open311::Endpoint::Schema; +use Moo; +use Data::Rx; + +use Open311::Endpoint::Schema::Comma; +use Open311::Endpoint::Schema::Regex; + +use Carp 'confess'; +has endpoint => ( + is => 'ro', + handles => [qw/ + get_jurisdiction_id_required_clause + get_jurisdiction_id_optional_clause + get_identifier_type + /], +); + +sub enum { + my ($self, $type, @values) = @_; + return { + type => '//any', + of => [ map { + { + type => $type, + value => $_, + } + } @values ], + }; +} + +sub format_boolean { + my ($self, $value) = @_; + return $value ? 'true' : 'false'; +} + +has schema => ( + is => 'lazy', + default => sub { + my $self = shift; + + my $schema = Data::Rx->new({ + sort_keys => 1, + prefix => { + open311 => 'tag:wiki.open311.org,GeoReport_v2:rx/', + }, + type_plugins => [qw( + Open311::Endpoint::Schema::Comma + Open311::Endpoint::Schema::Regex + )], + }); + + $schema->learn_type( 'tag:wiki.open311.org,GeoReport_v2:rx/bool', + $self->enum( '//str', qw[ true false ] )); + + $schema->learn_type( 'tag:wiki.open311.org,GeoReport_v2:rx/datetime', + { + type => '/open311/regex', + pattern => qr{ + ^ + \d{4} - \d{2} - \d{2} # yyyy-mm-dd + T + \d{2} : \d{2} : \d{2} # hh:mm:ss + (?: + Z # "Zulu" time, e.g. UTC + | [+-] \d{2} : \d{2} # +/- hh:mm offset + ) + $ + }ax, # use ascii semantics so /d means [0-9], and allow formatting + message => "found value isn't a datetime", + }); + + $schema->learn_type( 'tag:wiki.open311.org,GeoReport_v2:rx/example/identifier', + { + type => '/open311/regex', + pattern => qr{^ \w+ $}ax, + message => "found value isn't a valid identifier", + }); + + $schema->learn_type( 'tag:wiki.open311.org,GeoReport_v2:rx/status', + $self->enum( '//str', qw[ open closed ] )); + + $schema->learn_type( 'tag:wiki.open311.org,GeoReport_v2:rx/post_type', + $self->enum( '//str', qw[ realtime batch blackbox ] )); + + $schema->learn_type( 'tag:wiki.open311.org,GeoReport_v2:rx/service', + { + type => '//rec', + required => { + service_name => '//str', + type => '/open311/post_type', + metadata => '/open311/bool', + description => '//str', + service_code => '//str', + }, + optional => { + keywords => '//str', + group => '//str', + } + } + ); + $schema->learn_type( 'tag:wiki.open311.org,GeoReport_v2:rx/value', + { + type => '//rec', + required => { + key => '//str', + name => '//str', + } + } + ); + + $schema->learn_type( 'tag:wiki.open311.org,GeoReport_v2:rx/attribute', + { + type => '//rec', + required => { + code => '//str', + datatype => $self->enum( '//str', qw[ string number datetime text singlevaluelist multivaluelist ] ), + datatype_description => '//str', + description => '//str', + order => '//int', + required => '/open311/bool', + variable => '/open311/bool', + }, + optional => { + values => { + type => '//arr', + contents => '/open311/value', + }, + }, + } + ); + + $schema->learn_type( 'tag:wiki.open311.org,GeoReport_v2:rx/service_definition', + { + type => '//rec', + required => { + service_code => '//str', + attributes => { + type => '//arr', + contents => '/open311/attribute', + } + }, + } + ); + $schema->learn_type( 'tag:wiki.open311.org,GeoReport_v2:rx/service_request', + { + type => '//rec', + required => { + service_request_id => $self->get_identifier_type('service_request_id'), + status => '/open311/status', + service_name => '//str', + service_code => $self->get_identifier_type('service_code'), + requested_datetime => '/open311/datetime', + updated_datetime => '/open311/datetime', + address => '//str', + address_id => '//str', + zipcode => '//str', + lat => '//num', + long => '//num', + media_url => '//str', + }, + optional => { + request => '//str', + description => '//str', + agency_responsible => '//str', + service_notice => '//str', + }, + } + ); + + return $schema; + }, +); + +1; |