Condition.pm 2.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. package SugarTrail::Template::Condition;
  2. # condition
  3. # new()
  4. # parse(string)
  5. # match(data)
  6. use strict;
  7. use warnings;
  8. sub _equals {
  9. my $a = shift;
  10. my $b = $_[0]->[0];
  11. return $a eq $b;
  12. }
  13. sub _regex {
  14. my $a = shift;
  15. my $b = $_[0]->[0];
  16. return $a =~ m/$b/;
  17. }
  18. sub new {
  19. my $class = shift;
  20. my $self = {};
  21. $self->{string} = shift;
  22. $self->{handlers} = {
  23. '==' => \&_equals,
  24. '>=' => \&_greater_or_eq,
  25. '<=' => \&_less_or_eq,
  26. '=@' => \&_in,
  27. '=~' => \&_regex,
  28. };
  29. $self->{parsed} = 0;
  30. $self->{warnings} = [];
  31. return bless $self, $class;
  32. }
  33. # parse condition from its string version
  34. sub parse {
  35. my $self = shift;
  36. my $string = $self->{string};
  37. return if $self->{parsed};
  38. # cut spaces
  39. $string =~ s/^\s+//;
  40. $string =~ s/\s+$//;
  41. # get name, operator, value(s)
  42. my ($n, $o, $v) = $string =~ m/([a-zA-Z0-9_ ]+)([<>=~+\-*@]*)(.*)/;
  43. return unless $n;
  44. # cut inner spaces
  45. $n =~ s/\s+$//;
  46. $o =~ s/\s+$//;
  47. $o =~ s/^\s+//;
  48. $v =~ s/\s+$//;
  49. # split vlues
  50. my @v = split m/\s*,\s*/, $v;
  51. # assign
  52. $self->{n} = $n;
  53. $self->{o} = $o;
  54. $self->{v} = \@v;
  55. $self->{parsed}++;
  56. }
  57. # match the cond against params
  58. sub __match {
  59. my $self = shift;
  60. my $params = shift;
  61. my $name = $self->{n}; # what is the topic
  62. my $op = $self->{o}; # what op to use
  63. my $have = $self->{v}; # what we have in this step
  64. my $want = $params->{$name}; # what they want
  65. # warn if condition cannot be decided due to missing param
  66. unless ($want) {
  67. $self->warn( sprintf (
  68. "undecided condition: %s; did you forget to specify %s?",
  69. $self->{string},
  70. $name
  71. ));
  72. return 1;
  73. }
  74. # execute the right handler or warn it does not exist
  75. if (exists $self->{handlers}->{$op}) {
  76. return &{ $self->{handlers}->{$op} }($want, $have);
  77. } else {
  78. $self->warn("unknown operator: $op");
  79. return 1;
  80. }
  81. }
  82. # wrapper to __match(); adds warning list
  83. sub match {
  84. my $self = shift;
  85. my $params = shift;
  86. $self->parse();
  87. $self->{result} = $self->__match($params);
  88. return $self->{result}, $self->{warnings};
  89. }
  90. sub warn {
  91. my $self = shift;
  92. my $text = shift;
  93. push @{$self->{warnings}}, {
  94. time => time,
  95. text => $text
  96. };
  97. }
  98. 1;