package DateTime::Format::Builder::Parser::generic; { $DateTime::Format::Builder::Parser::generic::VERSION = '0.81'; } use strict; use warnings; use Carp; use Params::Validate qw( validate SCALAR CODEREF UNDEF ); sub new { my $class = shift; bless {@_}, $class; } sub generic_parser { my $class = shift; my %args = validate( @_, { ( map { $_ => { type => CODEREF, optional => 1 } } qw( on_match on_fail preprocess postprocess ) ), label => { type => SCALAR | UNDEF, optional => 1 }, } ); my $label = $args{label}; my $callback = ( exists $args{on_match} or exists $args{on_fail} ) ? 1 : undef; return sub { my ( $self, $date, $p, @args ) = @_; return unless defined $date; my %p; %p = %$p if $p; # Look! A Copy! my %param = ( self => $self, ( defined $label ? ( label => $label ) : () ), ( @args ? ( args => \@args ) : () ), ); # Preprocess - can modify $date and fill %p if ( $args{preprocess} ) { $date = $args{preprocess} ->( input => $date, parsed => \%p, %param ); } my $rv = $class->do_match( $date, @args ) if $class->can('do_match'); # Funky callback thing if ($callback) { my $type = defined $rv ? "on_match" : "on_fail"; $args{$type}->( input => $date, %param ) if $args{$type}; } return unless defined $rv; my $dt; $dt = $class->post_match( $date, $rv, \%p ) if $class->can('post_match'); # Allow post processing. Return undef if regarded as failure if ( $args{postprocess} ) { my $rv = $args{postprocess}->( parsed => \%p, input => $date, post => $dt, %param, ); return unless $rv; } # A successful match! $dt = $class->make( $date, $dt, \%p ) if $class->can('make'); return $dt; }; } { no strict 'refs'; for (qw( valid_params params )) { *$_ = *{"DateTime::Format::Builder::Parser::$_"}; } } 1; # ABSTRACT: Useful routines __END__ =pod =head1 NAME DateTime::Format::Builder::Parser::generic - Useful routines =head1 VERSION version 0.81 =head1 METHODS =head2 Useful =head3 new Standard constructor. Returns a blessed hash; any arguments are placed in the hash. This is useful for storing information between methods. =head3 generic_parser This is a method provided solely for the benefit of C implementations. It semi-neatly abstracts a lot of the work involved. Basically, it takes parameters matching the assorted callbacks from the parser declarations and makes a coderef out of it all. Currently recognized callbacks are: =over 4 =item * on_match =item * on_fail =item * preprocess =item * postprocess =back =head2 Methods for subclassing These are methods you should define when writing your own subclass. B: these methods do not exist in this class. There is no point trying to call C<< $self->SUPER::do_match( ... ) >>. =head3 do_match C is the first phase. Arguments are the date and @args. C, C