Group
Extension

WWW-FBX/lib/WWW/FBX/API.pm

package WWW::FBX::API;
use 5.014001;
use Moose();
use Carp::Clan qw/^(?:WWW::FBX|Moose|Class::MOP)/;
use Moose::Exporter;
use URI::Escape;

use namespace::autoclean;

Moose::Exporter->setup_import_methods(
    with_caller => [ qw/api_url fbx_api_method/ ],
);

my $_api_url;

sub api_url { $_api_url = $_[1]; }

sub fbx_api_method {
    my $caller = shift;
    my $name   = shift;
    my %options = (
        @_,
    );
    my $args;

    #Remove trailing _
    $name =~ s/_$//;

    my $class = Moose::Meta::Class->initialize($caller);

    my ($arg_names, $all_args) = @options{qw/required params/};

    my $code = sub {
        my $self = shift;
        my $args = ref $_[-1] eq 'HASH' ? { %{pop @_} } : {};

        croak sprintf "$name expected %d args", scalar @$all_args if @_ > @$all_args;

        # promote positional args to named args
        for ( my $i = 0; @_; ++$i ) {
            my $param = $all_args->[$i];
            croak "duplicate param $param: both positional and named"
                if exists $args->{$param};

            $args->{$param} = shift;
        }

        for my $arg (keys %$args) {
            unless ( grep { $_ eq $arg } @$all_args ) {
                die "Unknown argument $arg for $name\n" , "Description:$options{description}" ,
                    "Params:", join(",",@$all_args), "\nRequired:", join(",", @$arg_names), "\n" ;
            }
        }

        for my $req (@$arg_names) {
            unless ( grep { $_ eq $req } keys %$args or !defined ($args->{req}) ) {
                die "Missing required param $req for $name\n", "Description:$options{description}" ,
                    "Params:", join(",",@$all_args), "\nRequired:", join(",", @$arg_names), "\n" ;
            }
        }
        my $path = $options{path};
        $path .= delete $args->{suff} if exists $args->{suff};

        my $uri = URI->new( $self->base_url . "$_api_url/$path");

        return $self->_json_request(
            $options{method},
            $uri,
            $args,
            $options{content_type}
        );
    };
    #Add method with name and Class::MOP::Method
    $class->add_method(
        $name,
        WWW::FBX::Meta::Method->new(
            name         => $name,
            package_name => $caller,
            body         => $code,
            %options,
        ),
    );

}

package WWW::FBX::Meta::Method;
use Moose;
use Carp::Clan qw/^(?:WWW::FBX|Moose|Class::MOP)/;
extends 'Moose::Meta::Method';

use namespace::autoclean;

has description     => ( isa => 'Str', is => 'ro', required => 1 );
has path            => ( isa => 'Str', is => 'ro', required => 1 );
has method          => ( isa => 'Str', is => 'ro', default => 'GET' );
has params          => ( isa => 'ArrayRef[Str]', is => 'ro', default => sub { [] } );
has required        => ( isa => 'ArrayRef[Str]', is => 'ro', default => sub { [] } );
has returns         => ( isa => 'Str', is => 'ro', predicate => 'has_returns' );
has content_type    => ( isa => 'Str', is => 'ro', default => '' );
has suff            => ( isa => 'Str', is => 'ro', default => '' );

#Build hash where keys are attribute names
my %valid_attribute_names = map { $_->init_arg => 1 }
                            __PACKAGE__->meta->get_all_attributes;

sub new {
    my $class = shift;
    my %args  = @_;

    #Stack arguments that are not expected attributes
    my @invalid_attributes = grep { !$valid_attribute_names{$_} } keys %args;
    croak "unexpected argument(s): @invalid_attributes" if @invalid_attributes;

    #Create method
    $class->SUPER::wrap(@_);
}

1;
__END__

=encoding utf-8

=head1 NAME

WWW::FBX::API - Freebox API sugar

=head1 SYNOPSIS

    use WWW::FBX::API;

=head1 DESCRIPTION

WWW::FBX::API is API sugar

=head1 LICENSE

Copyright (C) Laurent Kislaire.

This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.

=head1 AUTHOR

Laurent Kislaire E<lt>teebeenator@gmail.comE<gt>

=cut



Powered by Groonga
Maintained by Kenichi Ishigaki <ishigaki@cpan.org>. If you find anything, submit it on GitHub.