package WWW::Asana::Role::NewFromResponse;
BEGIN {
$WWW::Asana::Role::NewFromResponse::AUTHORITY = 'cpan:GETTY';
}
{
$WWW::Asana::Role::NewFromResponse::VERSION = '0.003';
}
# ABSTRACT: Role which implements new_from_response for Asana classes
use MooX::Role;
use DateTime::Format::ISO8601;
use Class::Load ':all';
sub new_from_response {
my ( $class, $data ) = @_;
die "First parameter to new_From_response need to be a HashRef" unless ref $data eq 'HASH';
my %data = %{$data};
my %multi_mapping = (
followers => 'WWW::Asana::User',
workspaces => 'WWW::Asana::Workspace',
projects => 'WWW::Asana::Project',
tags => 'WWW::Asana::Tag',
);
my @needs_workspace = qw( projects tags );
my %single_mapping = (
assignee => 'WWW::Asana::User',
workspace => 'WWW::Asana::Workspace',
created_by => 'WWW::Asana::User',
);
my %new = %data;
# single mapping before multi mapping so that workspace is already there
for my $key (keys %single_mapping) {
if (exists $data{$key}) {
if ($data{$key}) {
my $target_class = $single_mapping{$key};
load_class($target_class) unless is_class_loaded($target_class);
$new{$key} = $target_class->new_from_response({
%{$data{$key}},
defined $data{client} ? ( client => $data{client} ) : (),
response => $data{response},
});
} else {
delete $new{$key};
}
}
}
for my $key (keys %multi_mapping) {
if (exists $data{$key}) {
$new{$key} = [];
my $target_class = $multi_mapping{$key};
for (@{$data{$key}}) {
load_class($target_class) unless is_class_loaded($target_class);
push @{$new{$key}}, $target_class->new_from_response({
%{$_},
defined $data{client} ? ( client => $data{client} ) : (),
(grep { $_ eq $key } @needs_workspace) ? ( workspace => $new{workspace} ) : (),
response => $data{response},
});
}
}
}
for my $key (qw( completed_at modified_at created_at due_on )) {
if (exists $data{$key}) {
if ($data{$key}) {
$new{$key} = DateTime::Format::ISO8601->parse_datetime($data{$key});
} else {
delete $new{$key};
}
}
}
return $class->new(%new);
}
1;
__END__
=pod
=head1 NAME
WWW::Asana::Role::NewFromResponse - Role which implements new_from_response for Asana classes
=head1 VERSION
version 0.003
=head1 METHODS
=head2 new_from_response
This function converts the data which is get from Asana into the required
attributes for generation of the given class. The first parameter must be
a HashRef. This HashRef can be spiced with B<client> and B<response> to give
a client which is able to handle the B<do> function, or to reflect the
response which leaded to this object.
The B<client> attribute is required if you want todo any calls to the Asana
API.
=head1 AUTHOR
Torsten Raudssus <torsten@raudss.us>
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2012 by Torsten Raudssus.
This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.
=cut