package RevBank::Global; use v5.32; use warnings; use experimental 'signatures'; # stable since v5.36 use POSIX qw(strftime); use RevBank::Amount; use RevBank::FileIO; { package RevBank::Exception::RejectInput; sub new($class, $reason) { return bless \$reason, $class; } sub reason($self) { return $$self; } } sub import { require RevBank::Plugins; require RevBank::Users; no strict 'refs'; my $caller = caller; *{"$caller\::ACCEPT"} = sub () { \1 }; *{"$caller\::ABORT"} = sub () { \2 }; *{"$caller\::REJECT"} = sub () { \3 }; *{"$caller\::NEXT"} = sub () { \4 }; *{"$caller\::DONE"} = sub () { \5 }; *{"$caller\::REDO"} = sub () { \6 }; *{"$caller\::slurp"} = \&RevBank::FileIO::slurp; *{"$caller\::spurt"} = \&RevBank::FileIO::spurt; *{"$caller\::rewrite"} = \&RevBank::FileIO::rewrite; *{"$caller\::append"} = \&RevBank::FileIO::append; *{"$caller\::with_lock"} = \&RevBank::FileIO::with_lock; *{"$caller\::parse_user"} = \&RevBank::Users::parse_user; *{"$caller\::parse_amount"} = sub ($amount) { defined $amount or return undef; length $amount or return undef; my @split = grep /\S/, split /([+-])/, $amount; my $posneg = 1; $amount = RevBank::Amount->new(0); for my $token (@split) { if ($token eq '-') { $posneg = $posneg == -1 ? 1 : -1; } elsif ($token eq '+') { $posneg ||= 1; } else { $posneg or return undef; # two terms in a row my $term = RevBank::Amount->parse_string($token) // return undef; $amount += $posneg * $term; $posneg = 0; } } $posneg and return undef; # last token must be term if ($amount->cents < 0) { die RevBank::Exception::RejectInput->new( "For our sanity, no negative amounts, please :)." ); } if ($amount->cents > 99900) { die RevBank::Exception::RejectInput->new( "That's way too much money." ); } return $amount; }; *{"$caller\::call_hooks"} = \&RevBank::Plugins::call_hooks; *{"$caller\::say"} = sub { print @_, "\n"; }; *{"$caller\::now"} = sub () { return strftime '%Y-%m-%d_%H:%M:%S', localtime; }; } __PACKAGE__->import; 1;