123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- package SugarTrail::Template::Condition;
- # condition
- # new()
- # parse(string)
- # match(data)
-
- use strict;
- use warnings;
-
- sub _equals {
- my $a = shift or return;
- my $b = $_[0]->[0];
- return $a eq $b;
- }
-
- sub _regex {
- my $a = shift or return;
- my $b = $_[0]->[0];
- return $a =~ m/$b/;
- }
-
- sub _in {
- my $a = shift or return;
- my %b = map { $_ => 1 } @_;
- return exists $b{$a};
- }
-
- sub new {
- my $class = shift;
- my $self = {};
- $self->{string} = shift;
- $self->{handlers} = {
- '==' => \&_equals,
- '>=' => \&_greater_or_eq,
- '<=' => \&_less_or_eq,
- '=@' => \&_in,
- '=~' => \&_regex,
- };
- $self->{parsed} = 0;
- $self->{warnings} = [];
- return bless $self, $class;
- }
-
- # parse condition from its string version
- sub parse {
- my $self = shift;
- my $string = $self->{string};
- return if $self->{parsed};
-
- # cut spaces
- $string =~ s/^\s+//;
- $string =~ s/\s+$//;
-
- # get name, operator, value(s)
- my ($n, $o, $v) = $string =~ m/([a-zA-Z0-9_ ]+)([<>=~+\-*@]*)(.*)/;
-
- # cut inner spaces
- $n =~ s/\s+$//;
- $o =~ s/\s+$//;
- $o =~ s/^\s+//;
- $v =~ s/\s+$//;
-
- # split vlues
- my @v = split m/\s*,\s*/, $v;
-
- unless ($string and $n and $o and @v) {
- $self->{error} = "syntax error: missing param name" unless $n;
- $self->{error} = "syntax error: missing operator" unless $o;
- $self->{error} = "syntax error: no values" unless @v;
- $self->{error} = "syntax error: no condition string" unless $string;
- return
- }
-
- # assign
- $self->{n} = $n;
- $self->{o} = $o;
- $self->{v} = \@v;
-
-
- $self->{parsed}++;
- }
-
- # match the cond against params
- sub __match {
- my $self = shift;
- my $params = shift;
-
- return if $self->{error};
-
- my $name = $self->{n}; # what is the topic
- my $op = $self->{o}; # what op to use
- my $have = $self->{v}; # what we have in this step
- my $want = $params->{$name}; # what they want
-
- # warn if condition cannot be decided due to missing param
- unless ($want) {
- $self->warn( sprintf (
- "undecided condition: %s; did you forget to specify %s?",
- $self->{string},
- $name
- ));
- }
-
- # execute the right handler or warn it does not exist
- if (exists $self->{handlers}->{$op}) {
- return &{ $self->{handlers}->{$op} }($want, $have);
- } else {
- $self->warn( sprintf (
- "unknown operator: '%s' in '%s'",
- $op,
- $self->{string}
- ));
- }
- }
-
- # wrapper to __match(); adds warning list
- sub match {
- my $self = shift;
- my $params = shift;
- $self->{error} = "";
- $self->parse();
- $self->{result} = $self->__match($params);
- return if $self->{error};
- return $self->{result}, $self->{warnings};
- }
-
- sub warn {
- my $self = shift;
- my $text = shift;
- push @{$self->{warnings}}, $text;
- }
-
- 1;
|