—use
strict;
use
warnings;
our
$VERSION
=
'0.83'
;
use
Carp;
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
=encoding UTF-8
=head1 NAME
DateTime::Format::Builder::Parser::generic - Useful routines
=head1 VERSION
version 0.83
=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<Parser>
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<Note>: these methods do not exist in this class. There is no point trying to
call C<< $self->SUPER::do_match( ... ) >>.
=head3 do_match
C<do_match> is the first phase. Arguments are the date and @args. C<self>,
C<label>, C<args>. Return value must be defined if you match successfully.
=head3 post_match
C<post_match> is called after the appropriate callback out of
C<on_match>/C<on_fail> is done. It's passed the date, the return value from
C<do_match> and the parsing hash.
Its return value is used as the C<post> argument to the C<postprocess>
callback, and as the second argument to C<make>.
=head3 make
C<make> takes the original input, the return value from C<post_match> and the
parsing hash and should return a C<DateTime> object or undefined.
=head2 Delegations
For use of C<Parser>, this module also delegates C<valid_params> and
C<params>. This is just convenience to save typing the following:
DateTime::Format::Builder::Parser->valid_params(...)
Instead we get to type:
$self->valid_params(...);
__PACKAGE__->valid_params(...);
=head1 WRITING A SUBCLASS
Rather than attempt to explain how it all works, I think it's best if you take
a look at F<Regex.pm> and F<Strptime.pm> as examples and work from there.
=head1 SEE ALSO
C<datetime@perl.org> mailing list.
L<perl>, L<DateTime>, L<DateTime::Format::Builder>,
L<DateTime::Format::Builder::Parser>.
=head1 SUPPORT
Bugs may be submitted at L<https://github.com/houseabsolute/DateTime-Format-Builder/issues>.
I am also usually active on IRC as 'autarch' on C<irc://irc.perl.org>.
=head1 SOURCE
The source code repository for DateTime-Format-Builder can be found at L<https://github.com/houseabsolute/DateTime-Format-Builder>.
=head1 AUTHORS
=over 4
=item *
Dave Rolsky <autarch@urth.org>
=item *
Iain Truskett <spoon@cpan.org>
=back
=head1 COPYRIGHT AND LICENSE
This software is Copyright (c) 2020 by Dave Rolsky.
This is free software, licensed under:
The Artistic License 2.0 (GPL Compatible)
The full text of the license can be found in the
F<LICENSE> file included with this distribution.
=cut