package Bot::Cobalt::Common; $Bot::Cobalt::Common::VERSION = '0.021002'; use v5.10; use strictures 2; use Carp; use List::Objects::WithUtils; use Import::Into; use Bot::Cobalt::Utils (); use IRC::Utils (); use Object::Pluggable::Constants (); use Try::Tiny (); use Types::Standard (); use List::Objects::Types (); our $ImportMap = hash( string => hash( 'Bot::Cobalt::Utils' => array( qw/ rplprintf color glob_to_re glob_to_re_str glob_grep / ), 'IRC::Utils' => array( qw/ lc_irc eq_irc uc_irc decode_irc strip_color strip_formatting / ), ), errors => hash( 'Carp' => array(qw/carp croak confess/), ), passwd => hash( 'Bot::Cobalt::Utils' => array( qw/ mkpasswd passwdcmp / ), ), time => hash( 'Bot::Cobalt::Utils' => array( qw/ timestr_to_secs secs_to_timestr secs_to_str secs_to_str_y / ), ), validate => hash( 'IRC::Utils' => array( qw/ is_valid_nick_name is_valid_chan_name / ), ), host => hash( 'IRC::Utils' => array( qw/ parse_user normalize_mask matches_mask / ), ), constant => hash( 'Object::Pluggable::Constants' => array( ':ALL' ), ), types => hash( 'Types::Standard' => array( -types ), 'List::Objects::Types' => array( -types ), ), ); my $FuncMap = $ImportMap ->values ->map(sub { my @func_pkg_pairs; my $iter = $_->iter; while (my ($pkg, $opts) = $iter->()) { $opts->visit(sub { my $maybe_prefix = substr $_, 0, 1; push @func_pkg_pairs, ($_ => $pkg) unless $maybe_prefix eq ':' or $maybe_prefix eq '-' }) } @func_pkg_pairs }) ->inflate; sub import { my (undef, @items) = @_; my $target = caller; feature->import( ':5.10' ); strictures->import::into($target); Try::Tiny->import::into($target); my $toimport = hash; # : or - prefixed tags are valid, everything else is a func/symbol: my (@tags, @funcs); for my $item (@items) { my $maybe_prefix = substr $item, 0, 1; if ($maybe_prefix eq ':' || $maybe_prefix eq '-') { push @tags, lc substr $item, 1; } else { push @funcs, $item; } } @tags = $ImportMap->keys->all if grep {; $_ eq 'all' } @tags # empty import implies all: or !@tags and !@funcs; # groups/tags: for my $tag (@tags) { my $groups = $ImportMap->get($tag) || confess "Import failed; tag '$tag' not exported"; for my $pkg ($groups->keys->all) { if ($toimport->exists($pkg)) { $toimport->get($pkg)->push( $groups->get($pkg)->all ) } else { $toimport->set( $pkg => $groups->get($pkg) ) } } } # individual symbols: for my $func (@funcs) { my $pkg = $FuncMap->get($func) || confess "Import failed; function '$func' not exported"; if ($toimport->exists($pkg)) { $toimport->get($pkg)->push($func) } else { $toimport->set( $pkg => array($func) ) } } my $iter = $toimport->iter; my @failed; while (my ($pkg, $optlist) = $iter->()) { my $importstr = $optlist->has_any ? "use $pkg qw/" . $optlist->uniq->join(' ') . "/;" : "use $pkg;"; my $c = "package $target; $importstr; 1"; local $@; eval $c and not $@ or carp $@ and push @failed, $pkg; } if (@failed) { croak 'Failed to import '. join ', ', @failed } 1 } 1; __END__ =pod =head1 NAME Bot::Cobalt::Common - Import commonly-used tools and constants =head1 SYNOPSIS package Bot::Cobalt::Plugin::User::MyPlugin; ## Import useful stuff: use Bot::Cobalt::Common; =head1 DESCRIPTION This is a small exporter module providing easy inclusion of commonly used tools and constants to make life easier on plugin authors. L<strictures> are also enabled. This will turn on 'strict' and make (most) warnings fatal. L<Try::Tiny> is always imported. =head2 Exported =head3 Constants =over =item * PLUGIN_EAT_NONE (L<Object::Pluggable::Constants>) =item * PLUGIN_EAT_ALL (L<Object::Pluggable::Constants>) =back =head3 Moo types All of the L<Types::Standard> and L<List::Objects::Types> types are exported. =head3 IRC::Utils See L<IRC::Utils> for details. =head4 String-related decode_irc lc_irc uc_irc eq_irc strip_color strip_formatting =head4 Hostmasks parse_user normalize_mask matches_mask =head4 Nicknames and channels is_valid_nick_name is_valid_chan_name =head3 Bot::Cobalt::Utils See L<Bot::Cobalt::Utils> for details. =head4 String-related rplprintf color =head4 Globs and matching glob_to_re glob_to_re_str glob_grep =head4 Passwords mkpasswd passwdcmp =head4 Time parsing timestr_to_secs secs_to_timestr secs_to_str secs_to_str_y =head3 Carp =head4 Warnings carp =head4 Errors croak confess =head2 Exported tags You can load groups of commands by importing named tags: use Bot::Cobalt::Common qw/ :types :string /; =head3 constant Exports PLUGIN_EAT_NONE, PLUGIN_EAT_ALL constants from L<Object::Pluggable>. =head3 errors Exports carp, croak, and confess from L<Carp>. =head3 host Exports parse_user, normalize_mask, and matches_mask from L<IRC::Utils>. =head3 passwd Exports mkpasswd and passwdcmp from L<App::bmkpasswd>. =head3 string Exports from L<Bot::Cobalt::Utils>: color, rplprintf, glob_to_re, glob_to_re_str, glob_grep Exports from L<IRC::Utils>: lc_irc, eq_irc, uc_irc, decode_irc, strip_color, strip_formatting =head3 time Exports timestr_to_secs, secs_to_timestr, secs_to_str, and secs_to_str_y from L<Bot::Cobalt::Utils>. =head3 types Exports all L<Type::Tiny> types from L<List::Objects::Types> and L<Types::Standard>. =head3 validate Exports is_valid_nick_name and is_valid_chan_name from L<IRC::Utils>. =head1 AUTHOR Jon Portnoy <avenj@cobaltirc.org> =cut