Declare-CLI

 view release on metacpan or  search on metacpan

lib/Declare/Opts.pm  view on Meta::CPAN

package Declare::Opts;
use strict;
use warnings;

our $VERSION = "0.009";

use Carp qw/croak/;

use Exporter::Declare qw{
    import
    gen_default_export
    default_export
};

gen_default_export 'OPTS_META' => sub {
    my ( $class, $caller ) = @_;
    my $meta = $class->new();
    $meta->{class} = $caller;
    return sub { $meta };
};

default_export opt        => sub { caller->OPTS_META->opt( @_ )   };
default_export parse_opts => sub { caller->OPTS_META->parse( @_ ) };
default_export opt_info   => sub { caller->OPTS_META->info        };

sub class   { shift->{class}   }
sub opts    { shift->{opts}    }
sub default { shift->{default} }

sub new {
    my $class = shift;
    my ( %opts ) = @_;

    my $self = bless { opts => {}, default => {} } => $class;
    $self->opt( $_, $opts{$_} ) for keys %opts;

    return $self;
}

sub valid_opt_params {
    return qr/^(alias|list|bool|default|check|transform|description)$/;
}

sub opt {
    my $self = shift;
    my ( $name, %config ) = @_;

    croak "opt '$name' already defined"
        if $self->opts->{$name};

    for my $prop ( keys %config ) {
        next if $prop =~ $self->valid_opt_params;
        croak "invalid opt property: '$prop'";
    }

    $config{name} = $name;

    croak "'check' cannot be used with 'bool'"
        if $config{bool} && $config{check};

    croak "'transform' cannot be used with 'bool'"
        if $config{bool} && $config{transform};

    croak "opt properties 'list' and 'bool' are mutually exclusive"
        if $config{list} && $config{bool};

    if (exists $config{default}) {
        croak "References cannot be used in default, wrap them in a sub."
            if ref $config{default} && ref $config{default} ne 'CODE';
        $self->default->{$name} = $config{default};
    }

    if ( exists $config{check} ) {
        my $ref = ref $config{check};
        croak "'$config{check}' is not a valid value for 'check'"
            if ($ref && $ref !~ m/^(CODE|Regexp)$/)
            || (!$ref && $config{check} !~ m/^(file|dir|number)$/);
    }

    if ( exists $config{alias} ) {
        my $aliases = ref $config{alias} ?   $config{alias}
                                         : [ $config{alias} ];

        $config{_alias} = { map { $_ => 1 } @$aliases };

        for my $alias ( @$aliases ) {
            croak "Cannot use alias '$alias', name is already taken by another opt."
                if $self->opts->{$alias};

            $self->opts->{$alias} = \%config;
        }
    }

    $self->opts->{$name} = \%config;

 view all matches for this distribution
 view release on metacpan -  search on metacpan

( run in 1.417 second using v1.00-cache-2.02-grep-82fe00e-cpan-f5108d614456 )