|
Packit |
9002b2 |
package DateTime::Format::Builder::Parser::generic;
|
|
Packit |
9002b2 |
{
|
|
Packit |
9002b2 |
$DateTime::Format::Builder::Parser::generic::VERSION = '0.81';
|
|
Packit |
9002b2 |
}
|
|
Packit |
9002b2 |
use strict;
|
|
Packit |
9002b2 |
use warnings;
|
|
Packit |
9002b2 |
use Carp;
|
|
Packit |
9002b2 |
use Params::Validate qw(
|
|
Packit |
9002b2 |
validate SCALAR CODEREF UNDEF
|
|
Packit |
9002b2 |
);
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
sub new {
|
|
Packit |
9002b2 |
my $class = shift;
|
|
Packit |
9002b2 |
bless {@_}, $class;
|
|
Packit |
9002b2 |
}
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
sub generic_parser {
|
|
Packit |
9002b2 |
my $class = shift;
|
|
Packit |
9002b2 |
my %args = validate(
|
|
Packit |
9002b2 |
@_,
|
|
Packit |
9002b2 |
{
|
|
Packit |
9002b2 |
(
|
|
Packit |
9002b2 |
map { $_ => { type => CODEREF, optional => 1 } }
|
|
Packit |
9002b2 |
qw(
|
|
Packit |
9002b2 |
on_match on_fail preprocess postprocess
|
|
Packit |
9002b2 |
)
|
|
Packit |
9002b2 |
),
|
|
Packit |
9002b2 |
label => { type => SCALAR | UNDEF, optional => 1 },
|
|
Packit |
9002b2 |
}
|
|
Packit |
9002b2 |
);
|
|
Packit |
9002b2 |
my $label = $args{label};
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
my $callback
|
|
Packit |
9002b2 |
= ( exists $args{on_match} or exists $args{on_fail} ) ? 1 : undef;
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
return sub {
|
|
Packit |
9002b2 |
my ( $self, $date, $p, @args ) = @_;
|
|
Packit |
9002b2 |
return unless defined $date;
|
|
Packit |
9002b2 |
my %p;
|
|
Packit |
9002b2 |
%p = %$p if $p; # Look! A Copy!
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
my %param = (
|
|
Packit |
9002b2 |
self => $self,
|
|
Packit |
9002b2 |
( defined $label ? ( label => $label ) : () ),
|
|
Packit |
9002b2 |
( @args ? ( args => \@args ) : () ),
|
|
Packit |
9002b2 |
);
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
# Preprocess - can modify $date and fill %p
|
|
Packit |
9002b2 |
if ( $args{preprocess} ) {
|
|
Packit |
9002b2 |
$date = $args{preprocess}
|
|
Packit |
9002b2 |
->( input => $date, parsed => \%p, %param );
|
|
Packit |
9002b2 |
}
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
my $rv = $class->do_match( $date, @args ) if $class->can('do_match');
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
# Funky callback thing
|
|
Packit |
9002b2 |
if ($callback) {
|
|
Packit |
9002b2 |
my $type = defined $rv ? "on_match" : "on_fail";
|
|
Packit |
9002b2 |
$args{$type}->( input => $date, %param ) if $args{$type};
|
|
Packit |
9002b2 |
}
|
|
Packit |
9002b2 |
return unless defined $rv;
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
my $dt;
|
|
Packit |
9002b2 |
$dt = $class->post_match( $date, $rv, \%p )
|
|
Packit |
9002b2 |
if $class->can('post_match');
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
# Allow post processing. Return undef if regarded as failure
|
|
Packit |
9002b2 |
if ( $args{postprocess} ) {
|
|
Packit |
9002b2 |
my $rv = $args{postprocess}->(
|
|
Packit |
9002b2 |
parsed => \%p,
|
|
Packit |
9002b2 |
input => $date,
|
|
Packit |
9002b2 |
post => $dt,
|
|
Packit |
9002b2 |
%param,
|
|
Packit |
9002b2 |
);
|
|
Packit |
9002b2 |
return unless $rv;
|
|
Packit |
9002b2 |
}
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
# A successful match!
|
|
Packit |
9002b2 |
$dt = $class->make( $date, $dt, \%p ) if $class->can('make');
|
|
Packit |
9002b2 |
return $dt;
|
|
Packit |
9002b2 |
};
|
|
Packit |
9002b2 |
}
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
{
|
|
Packit |
9002b2 |
no strict 'refs';
|
|
Packit |
9002b2 |
for (qw( valid_params params )) {
|
|
Packit |
9002b2 |
*$_ = *{"DateTime::Format::Builder::Parser::$_"};
|
|
Packit |
9002b2 |
}
|
|
Packit |
9002b2 |
}
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
1;
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
# ABSTRACT: Useful routines
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
__END__
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
=pod
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
=head1 NAME
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
DateTime::Format::Builder::Parser::generic - Useful routines
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
=head1 VERSION
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
version 0.81
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
=head1 METHODS
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
=head2 Useful
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
=head3 new
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
Standard constructor. Returns a blessed hash; any arguments are placed
|
|
Packit |
9002b2 |
in the hash. This is useful for storing information between methods.
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
=head3 generic_parser
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
This is a method provided solely for the benefit of
|
|
Packit |
9002b2 |
C<Parser> implementations. It semi-neatly abstracts
|
|
Packit |
9002b2 |
a lot of the work involved.
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
Basically, it takes parameters matching the assorted
|
|
Packit |
9002b2 |
callbacks from the parser declarations and makes a coderef
|
|
Packit |
9002b2 |
out of it all.
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
Currently recognized callbacks are:
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
=over 4
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
=item *
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
on_match
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
=item *
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
on_fail
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
=item *
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
preprocess
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
=item *
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
postprocess
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
=back
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
=head2 Methods for subclassing
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
These are methods you should define when writing your own subclass.
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
B<Note>: these methods do not exist in this class. There is no point
|
|
Packit |
9002b2 |
trying to call C<< $self->SUPER::do_match( ... ) >>.
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
=head3 do_match
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
C<do_match> is the first phase. Arguments are the date and @args.
|
|
Packit |
9002b2 |
C<self>, C<label>, C<args>. Return value must be defined if you match
|
|
Packit |
9002b2 |
successfully.
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
=head3 post_match
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
C<post_match> is called after the appropriate callback out of
|
|
Packit |
9002b2 |
C<on_match>/C<on_fail> is done. It's passed the date, the return
|
|
Packit |
9002b2 |
value from C<do_match> and the parsing hash.
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
Its return value is used as the C<post> argument to the C<postprocess>
|
|
Packit |
9002b2 |
callback, and as the second argument to C<make>.
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
=head3 make
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
C<make> takes the original input, the return value from C<post_match>
|
|
Packit |
9002b2 |
and the parsing hash and should return a C<DateTime> object or
|
|
Packit |
9002b2 |
undefined.
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
=head2 Delegations
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
For use of C<Parser>, this module also delegates C<valid_params> and
|
|
Packit |
9002b2 |
C<params>. This is just convenience to save typing the following:
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
DateTime::Format::Builder::Parser->valid_params( blah )
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
Instead we get to type:
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
$self->valid_params( blah );
|
|
Packit |
9002b2 |
__PACKAGE__->valid_params( blah );
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
=head1 WRITING A SUBCLASS
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
Rather than attempt to explain how it all works, I think it's best if
|
|
Packit |
9002b2 |
you take a look at F<Regex.pm> and F<Strptime.pm> as examples and
|
|
Packit |
9002b2 |
work from there.
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
=head1 SUPPORT
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
See L<DateTime::Format::Builder> for details.
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
=head1 SEE ALSO
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
C<datetime@perl.org> mailing list.
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
http://datetime.perl.org/
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
L<perl>, L<DateTime>, L<DateTime::Format::Builder>,
|
|
Packit |
9002b2 |
L<DateTime::Format::Builder::Parser>.
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
=head1 AUTHORS
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
=over 4
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
=item *
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
Dave Rolsky <autarch@urth.org>
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
=item *
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
Iain Truskett
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
=back
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
=head1 COPYRIGHT AND LICENSE
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
This software is Copyright (c) 2013 by Dave Rolsky.
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
This is free software, licensed under:
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
The Artistic License 2.0 (GPL Compatible)
|
|
Packit |
9002b2 |
|
|
Packit |
9002b2 |
=cut
|