Class-Usul
view release on metacpan or search on metacpan
lib/Class/Usul/TraitFor/OutputLogging.pm view on Meta::CPAN
package Class::Usul::TraitFor::OutputLogging;
use namespace::autoclean;
use Class::Usul::Constants qw( BRK FAILED FALSE NUL TRUE WIDTH );
use Class::Usul::Functions qw( abs_path emit emit_err throw );
use Class::Usul::Types qw( Bool SimpleStr );
use Text::Autoformat qw( autoformat );
use Moo::Role;
use Class::Usul::Options;
requires qw( config log );
# Public attributes
option 'locale' => is => 'lazy', isa => SimpleStr, format => 's',
documentation => 'Loads the specified language message catalogue',
builder => sub { $_[ 0 ]->config->locale }, short => 'L';
option 'quiet' => is => 'ro', isa => Bool, default => FALSE,
documentation => 'Quiet the display of information messages',
reader => 'quiet_flag', short => 'q';
# Private attributes
has '_quiet_flag' => is => 'rw', isa => Bool,
builder => sub { $_[ 0 ]->quiet_flag },
lazy => TRUE, writer => '_set__quiet_flag';
# Private methods
my $_loc = sub {
my ($self, $text, $opts, $quote) = @_; $opts //= {};
return $self->localize( $text // '[no message]', {
locale => $self->locale,
no_quote_bind_values => $quote // $opts->{no_quote_bind_values} // FALSE,
params => $opts->{args} // [] } );
};
# Public methods
sub add_leader {
my ($self, $text, $opts) = @_; $text or return NUL; $opts //= {};
my $leader = $opts->{no_lead} ? NUL : (ucfirst $self->config->name).BRK;
if ($opts->{fill}) {
my $width = $opts->{width} // WIDTH;
$text = autoformat $text, { right => $width - 1 - length $leader };
}
return join "\n", map { (m{ \A $leader }mx ? NUL : $leader).$_ }
split m{ \n }mx, $text;
}
sub error {
my ($self, $text, $opts) = @_; $text = $self->$_loc( $text, $opts );
$self->log->error( $_ ) for (split m{ \n }mx, "${text}");
emit_err $self->add_leader( $text, $opts );
return TRUE;
}
sub fatal {
my ($self, $text, $opts) = @_; my (undef, $file, $line) = caller 0;
my $posn = ' at '.abs_path( $file )." line ${line}";
$text = $self->$_loc( $text, $opts ).$posn;
$self->log->alert( $_ ) for (split m{ \n }mx, $text);
emit_err $self->add_leader( $text, $opts );
exit FAILED;
}
sub info {
my ($self, $text, $opts) = @_;
$opts //= {}; $text = $self->$_loc( $text, $opts, TRUE );
$self->log->info( $_ ) for (split m{ [\n] }mx, $text);
$self->quiet or $opts->{quiet} or emit $self->add_leader( $text, $opts );
return TRUE;
}
sub loc {
my $self = shift; return $self->l10n->localizer( $self->locale, @_ );
}
sub output {
my ($self, $text, $opts) = @_;
$opts //= {}; $text = $self->$_loc( $text, $opts, TRUE );
my $code = sub {
$opts->{to} && $opts->{to} eq 'err' ? emit_err( @_ ) : emit( @_ );
};
$code->() if $opts->{cl};
$code->( $self->add_leader( $text, $opts ) );
$code->() if $opts->{nl};
return TRUE;
}
sub quiet {
my ($self, $v) = @_; defined $v or return $self->_quiet_flag; $v = !!$v;
$v != TRUE and throw 'Cannot turn quiet mode off';
return $self->_set__quiet_flag( $v );
}
sub warning {
my ($self, $text, $opts) = @_;
$opts //= {}; $text = $self->$_loc( $text, $opts );
$self->log->warn( $_ ) for (split m{ \n }mx, $text);
$self->quiet or $opts->{quiet} or emit $self->add_leader( $text, $opts );
return TRUE;
}
1;
__END__
=pod
=encoding utf-8
=head1 Name
Class::Usul::TraitFor::OutputLogging - Localised logging and command line output methods
=head1 Synopsis
use Moo;
extends 'Class::Usul';
with 'Class::Usul::TraitFor::OutputLogging';
=head1 Description
Localised logging and command line output methods
=head1 Configuration and Environment
Requires the following;
=over 3
=item C<config>
=item C<log>
=back
Defines the following command line options;
=over 3
=item C<L locale>
Print text and error messages in the selected language. If no language
catalogue is supplied prints text and errors in terse English. Defaults
to C<en>
=item C<q quiet_flag>
Quietens the usual started/finished information messages
=back
=head1 Subroutines/Methods
=head2 add_leader
( run in 0.534 second using v1.01-cache-2.11-cpan-71847e10f99 )