From 022152630a9084fbc604f0d06b0005d97747b50d Mon Sep 17 00:00:00 2001 From: Gianni Ceccarelli Date: Thu, 7 Nov 2013 11:32:13 +0000 Subject: migrate to Moo: forecast client --- lib/Types/DateTime.pm | 20 ++++++++++ lib/Types/URI.pm | 15 ++++++++ lib/WebService/ForecastIo.pm | 69 +++++++++++++++++----------------- lib/WebService/ForecastIo/Alert.pm | 31 +++++---------- lib/WebService/ForecastIo/DataBlock.pm | 23 ++++-------- lib/WebService/ForecastIo/DataPoint.pm | 30 ++++----------- lib/WebService/ForecastIo/DataSpan.pm | 11 ++++-- lib/WebService/ForecastIo/Response.pm | 28 +++++++------- lib/WebService/ForecastIo/Types.pm | 55 +++++++++++++++++++++++++++ 9 files changed, 170 insertions(+), 112 deletions(-) create mode 100644 lib/Types/DateTime.pm create mode 100644 lib/Types/URI.pm create mode 100644 lib/WebService/ForecastIo/Types.pm (limited to 'lib') diff --git a/lib/Types/DateTime.pm b/lib/Types/DateTime.pm new file mode 100644 index 0000000..d13f0d5 --- /dev/null +++ b/lib/Types/DateTime.pm @@ -0,0 +1,20 @@ +package Types::DateTime; +use strict; +use warnings; +use namespace::autoclean; +use Type::Library -base, -declare => 'DateTimeT'; +use Type::Utils -all; +use Types::Standard -types; + +class_type DateTimeT, { class => 'DateTime' }; +coerce DateTimeT, from Num, via { + require DateTime; + DateTime->from_epoch(epoch => $_ ); +}; +coerce DateTimeT, from Str, via { + require DateTime::Format::ISO8601; + s{([+-])(\d\d)(\d\d)\z}{$1$2:$3}; + DateTime::Format::ISO8601->new->parse_datetime($_) +}; + +1; diff --git a/lib/Types/URI.pm b/lib/Types/URI.pm new file mode 100644 index 0000000..0bb4ae5 --- /dev/null +++ b/lib/Types/URI.pm @@ -0,0 +1,15 @@ +package Types::URI; +use strict; +use warnings; +use namespace::autoclean; +use Type::Library -base, -declare => 'Uri'; +use Type::Utils -all; +use Types::Standard -types; + +class_type Uri, { class => 'URI' }; +coerce Uri, from Str, via { + require URI; + URI->new($_); +}; + +1; diff --git a/lib/WebService/ForecastIo.pm b/lib/WebService/ForecastIo.pm index c336378..0a2dfb3 100644 --- a/lib/WebService/ForecastIo.pm +++ b/lib/WebService/ForecastIo.pm @@ -1,29 +1,31 @@ package WebService::ForecastIo; -use Moose; -use MooseX::Types::URI 'Uri'; -use MooseX::Types::DateTime; -use MooseX::Params::Validate; -use Moose::Util::TypeConstraints; -use DateTime::Format::ISO8601; +use Moo; +use 5.10.0; +use Types::Standard -types,'slurpy'; +use Type::Utils -all; +use Types::URI 'Uri'; +use Types::DateTime 'DateTimeT'; +use Type::Params; use WebService::ForecastIo::Response; +use DateTime::TimeZone; +use namespace::autoclean; has base_uri => ( is => 'ro', isa => Uri, - coerce => 1, default => 'https://api.forecast.io/forecast', + coerce => Uri->coercion, ); has api_key => ( is => 'ro', - isa => 'Str', + isa => Str, required => 1, ); has user_agent => ( - is => 'ro', + is => 'lazy', isa => duck_type(['get']), - lazy_build => 1, ); sub _build_user_agent { require LWP::UserAgent; @@ -37,9 +39,9 @@ sub _build_user_agent { } sub _make_request_uri { - my ($self,%opts) = @_; + my ($self,$opts) = @_; - my ($lat,$lon,$time) = delete @opts{qw(latitude longitude time)}; + my ($lat,$lon,$time) = delete @$opts{qw(latitude longitude time)}; my $req_uri = $self->base_uri->clone; @@ -63,43 +65,40 @@ sub _make_request_uri { $time_str, ); - if ($opts{exclude}) { - $opts{exclude} = join ',',@{$opts{exclude}}; + if ($opts->{exclude}) { + $opts->{exclude} = join ',',@{$opts->{exclude}}; } - $req_uri->query_form(\%opts); + $req_uri->query_form($opts); return $req_uri; } -enum my $units_type=__PACKAGE__.'::units', - [qw(us si ca uk auto)]; -enum my $block_type=__PACKAGE__.'::block', - [qw(currently minutely hourly daily alerts flags sources)]; - -coerce 'DateTime', from 'Str', - via { - s{([+-])(\d\d)(\d\d)\z}{$1$2:$3}; - DateTime::Format::ISO8601->new->parse_datetime($_) - }; +my $units_type = enum [qw(us si ca uk auto)]; +my $block_type = enum [qw(currently minutely hourly daily alerts flags sources)]; sub request { - my ($self,%opts) = validated_hash( - \@_, - latitude => { isa => 'Num' }, - longitude => { isa => 'Num' }, - time => { isa => 'DateTime', optional => 1, coerce => 1 }, - units => { isa => $units_type, default => 'si' }, - exclude => { isa => "ArrayRef[$block_type]", default => sub { [] } }, - raw => { isa => 'Bool', default => 0 }, + state $argcheck = compile( + Object, Dict[ + latitude => Num, + longitude => Num, + time => Optional[DateTimeT], + units => Optional[$units_type], + exclude => Optional[ArrayRef[$block_type]], + raw => Optional[Bool], + ], ); + my ($self,$opts) = $argcheck->(@_); + $opts->{units} //= 'si'; + $opts->{exclude} //= []; + $opts->{raw} //= 0; - my $uri = $self->_make_request_uri(%opts); + my $uri = $self->_make_request_uri($opts); my $response = $self->user_agent->get($uri); if ($response->is_success) { my $json = $response->decoded_content; - return $json if $opts{raw}; + return $json if $opts->{raw}; my $res = WebService::ForecastIo::Response->new($json); return wantarray ? ($res,$json) : $res } diff --git a/lib/WebService/ForecastIo/Alert.pm b/lib/WebService/ForecastIo/Alert.pm index d402fa2..af826d8 100644 --- a/lib/WebService/ForecastIo/Alert.pm +++ b/lib/WebService/ForecastIo/Alert.pm @@ -1,38 +1,25 @@ package WebService::ForecastIo::Alert; -use Moose; -use Moose::Util::TypeConstraints; -use MooseX::Types::URI 'Uri'; -use MooseX::Types::DateTime; - -class_type 'WebService::ForecastIo::Alert'; - -subtype 'WebService::ForecastIo::AlertArray', - as 'ArrayRef[WebService::ForecastIo::Alert]'; - -coerce 'WebService::ForecastIo::Alert', from 'HashRef', - via { WebService::ForecastIo::Alert->new($_) }; - -coerce 'WebService::ForecastIo::AlertArray', from 'ArrayRef[HashRef]', - via { - my $array = $_; - [ map { WebService::ForecastIo::Alert->new($_) } - @$array ] - }; +use Moo; +use namespace::autoclean; +use Types::Standard -all; +use Types::URI 'Uri'; +use Types::DateTime 'DateTimeT'; has title => ( is => 'ro', - isa => 'Str', + isa => Str, ); has expires => ( is => 'ro', - isa => 'DateTime', - coerce => 1, + isa => DateTimeT, + coerce => DateTimeT->coercion, ); has uri => ( is => 'ro', isa => Uri, + coerce => Uri->coercion, ); 1; diff --git a/lib/WebService/ForecastIo/DataBlock.pm b/lib/WebService/ForecastIo/DataBlock.pm index 9885c42..2b737ca 100644 --- a/lib/WebService/ForecastIo/DataBlock.pm +++ b/lib/WebService/ForecastIo/DataBlock.pm @@ -1,28 +1,21 @@ package WebService::ForecastIo::DataBlock; -use Moose; -use Moose::Util::TypeConstraints; -use WebService::ForecastIo::DataPoint; +use Moo; +use namespace::autoclean; +use Types::Standard -all; +use WebService::ForecastIo::Types -all; use WebService::ForecastIo::DataSpan; -class_type 'WebService::ForecastIo::DataBlock'; - -coerce 'WebService::ForecastIo::DataBlock', from 'HashRef', - via { WebService::ForecastIo::DataBlock->new($_) }; - has [qw(summary icon)] => ( is => 'ro', - isa => 'Str', + isa => Str, ); has data => ( is => 'ro', - isa => 'WebService::ForecastIo::DataPointArray', - coerce => 1, - traits => [ 'Array' ], - handles => { - data_points => 'elements', - } + isa => DataPointArray, + coerce => DataPointArray->coercion, ); +sub data_points { @{$_[0]->data} } sub spans_by_string { my ($self,$field) = @_; diff --git a/lib/WebService/ForecastIo/DataPoint.pm b/lib/WebService/ForecastIo/DataPoint.pm index ba06fa1..47ef659 100644 --- a/lib/WebService/ForecastIo/DataPoint.pm +++ b/lib/WebService/ForecastIo/DataPoint.pm @@ -1,35 +1,21 @@ package WebService::ForecastIo::DataPoint; -use Moose; -use Moose::Util::TypeConstraints; -use MooseX::Types::DateTime; - -class_type 'WebService::ForecastIo::DataPoint'; - -subtype 'WebService::ForecastIo::DataPointArray', - as 'ArrayRef[WebService::ForecastIo::DataPoint]'; - -coerce 'WebService::ForecastIo::DataPoint', from 'HashRef', - via { WebService::ForecastIo::DataPoint->new($_) }; - -coerce 'WebService::ForecastIo::DataPointArray', from 'ArrayRef[HashRef]', - via { - my $array = $_; - [ map { WebService::ForecastIo::DataPoint->new($_) } - @$array ] - }; +use Moo; +use namespace::autoclean; +use Types::DateTime 'DateTimeT'; +use Types::Standard -all; has [qw( time sunriseTime sunsetTime precipIntensityMaxTime temperatureMinTime temperatureMaxTime )] => ( is => 'ro', - isa => 'DateTime', - coerce => 1, + isa => DateTimeT, + coerce => DateTimeT->coercion, ); has [qw(summary icon precipType)] => ( is => 'ro', - isa => 'Str', + isa => Str, ); has [qw( precipIntensity precipIntensityMax @@ -40,7 +26,7 @@ has [qw( precipIntensity precipIntensityMax cloudCover pressure visibility ozone )] => ( is => 'ro', - isa => 'Num', + isa => Num, ); 1; diff --git a/lib/WebService/ForecastIo/DataSpan.pm b/lib/WebService/ForecastIo/DataSpan.pm index 256f207..4911442 100644 --- a/lib/WebService/ForecastIo/DataSpan.pm +++ b/lib/WebService/ForecastIo/DataSpan.pm @@ -1,17 +1,20 @@ package WebService::ForecastIo::DataSpan; -use Moose; -use MooseX::Types::DateTime; +use Moo; +use namespace::autoclean; +use Types::DateTime 'DateTimeT'; has start_time => ( is => 'ro', - isa => 'DateTime', + isa => DateTimeT, + coerce => DateTimeT->coercion, required => 1, ); has stop_time => ( is => 'ro', writer => '_set_stop_time', - isa => 'DateTime', + isa => DateTimeT, + coerce => DateTimeT->coercion, required => 1, ); diff --git a/lib/WebService/ForecastIo/Response.pm b/lib/WebService/ForecastIo/Response.pm index e217c70..24c5324 100644 --- a/lib/WebService/ForecastIo/Response.pm +++ b/lib/WebService/ForecastIo/Response.pm @@ -1,46 +1,46 @@ package WebService::ForecastIo::Response; -use Moose; -use WebService::ForecastIo::DataPoint; -use WebService::ForecastIo::DataBlock; -use WebService::ForecastIo::Alert; +use Moo; +use namespace::autoclean; +use Types::Standard -all; +use WebService::ForecastIo::Types -all; use JSON; has 'currently' => ( is => 'ro', - isa => 'WebService::ForecastIo::DataPoint', - coerce => 1, + isa => DataPoint, + coerce => DataPoint->coercion, ); has [qw(daily hourly minutely)] => ( is => 'ro', - isa => 'WebService::ForecastIo::DataBlock', - coerce => 1, + isa => DataBlock, + coerce => DataBlock->coercion, ); has [qw(latitude longitude)] => ( is => 'ro', - isa => 'Num', + isa => Num, ); has timezone => ( is => 'ro', - isa => 'Str', + isa => Str, ); has offset => ( is => 'ro', - isa => 'Num', + isa => Num, ); has alerts => ( is => 'ro', - isa => 'WebService::ForecastIo::AlertArray', - coerce => 1, + isa => AlertArray, + coerce => AlertArray->coercion, ); has flags => ( is => 'ro', - isa => 'HashRef', + isa => HashRef, ); around BUILDARGS => sub { diff --git a/lib/WebService/ForecastIo/Types.pm b/lib/WebService/ForecastIo/Types.pm new file mode 100644 index 0000000..cc8dac2 --- /dev/null +++ b/lib/WebService/ForecastIo/Types.pm @@ -0,0 +1,55 @@ +package WebService::ForecastIo::Types; +use strict; +use warnings; +use namespace::autoclean; +use Type::Library -base, -declare => + qw( + Alert AlertArray + DataBlock + DataPoint DataPointArray + ); +use Type::Utils -all; +use Types::Standard -types; + +class_type Alert, { class => 'WebService::ForecastIo::Alert' }; + +declare AlertArray, as ArrayRef[Alert]; + +coerce Alert, from HashRef, via { + require WebService::ForecastIo::Alert; + WebService::ForecastIo::Alert->new($_); +}; + +coerce AlertArray, from ArrayRef[HashRef], via { + require WebService::ForecastIo::Alert; + my $array = $_; + [ map { WebService::ForecastIo::Alert->new($_) } + @$array ] +}; + + +class_type DataBlock, { class => 'WebService::ForecastIo::DataBlock' }; + +coerce DataBlock, from HashRef, via { + require WebService::ForecastIo::DataBlock; + WebService::ForecastIo::DataBlock->new($_); +}; + + +class_type DataPoint, { class => 'WebService::ForecastIo::DataPoint' }; + +declare DataPointArray, as ArrayRef[DataPoint]; + +coerce DataPoint, from HashRef, via { + require WebService::ForecastIo::DataPoint; + WebService::ForecastIo::DataPoint->new($_); +}; + +coerce DataPointArray, from ArrayRef[HashRef], via { + require WebService::ForecastIo::DataPoint; + my $array = $_; + [ map { WebService::ForecastIo::DataPoint->new($_) } + @$array ] +}; + +1; -- cgit v1.2.3