-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
copy Dispatcher from the November repo, continue work here
- Loading branch information
Ilya Belikin
committed
Apr 1, 2009
1 parent
82035d5
commit 5191b21
Showing
8 changed files
with
307 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
class Dispatcher { | ||
use Dispatcher::Rule; | ||
|
||
has @.rules; | ||
has $.default is rw; | ||
|
||
multi method add (Dispatcher::Rule $rule) { | ||
die "Only complete rules allowed" unless $rule.?is_complete; | ||
@!rules.push($rule); | ||
} | ||
|
||
multi method add (@pattern, Code $code) { | ||
my $rule = Dispatcher::Rule.new( pattern => @pattern, code => $code ); | ||
@!rules.push($rule); | ||
} | ||
|
||
multi method add (@rules) { | ||
# RAKUDO: rakudo doesn't know return values in for loops yet | ||
my $r; | ||
# RAKUDO: Larry -- "the default parameter to a block is now Object and | ||
# not Any" but this is NIY | ||
for @rules -> Object @pattern, $action { | ||
$r = self.add(@pattern, $action); | ||
} | ||
return $r; | ||
} | ||
|
||
method dispatch (@chunks) { | ||
my @matched = @!rules.grep: { .match(@chunks) }; | ||
|
||
if @matched { | ||
my $result = @matched[*-1].apply; | ||
.clear for @!rules; | ||
return $result; | ||
} | ||
elsif defined $.default { | ||
$.default(); | ||
} | ||
else { | ||
return Failure; | ||
} | ||
} | ||
} | ||
|
||
# vim:ft=perl6 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
class Dispatcher::Rule; | ||
has @.pattern; | ||
has @.args; | ||
|
||
has Str $.controller is rw; | ||
has Str $.action is rw; | ||
|
||
has Code $.code; | ||
|
||
method match (@chunks) { | ||
return False if @chunks != @!pattern; | ||
for @chunks Z @!pattern-> $chunk, Object $rule is copy { | ||
|
||
my $param; | ||
if $rule ~~ Pair { ($param, $rule) = $rule.kv } | ||
|
||
if ~$chunk ~~ $rule { | ||
if $param { | ||
self."$param" = (~$/ || ~$chunk); | ||
} else { | ||
# RAKUDO: /./ ~~ Regex us false, but /./ ~~ Code is true | ||
@!args.push($/ || $chunk) if $rule ~~ Code | Whatever; # should by Regex | Whatever | ||
} | ||
} | ||
else { | ||
self.clear; | ||
return False; | ||
} | ||
} | ||
return True; | ||
} | ||
|
||
method apply { | ||
# RAKUDO: die with FixedIntegerArray: index out of bounds! on test 01/3 | ||
#$!code(| @!args, controller => $.controller, action => $.action ); | ||
# workaround: | ||
if $!controller and $!action { | ||
$!code(| @!args,action => $.action, controller => $.controller ); | ||
} elsif $!action { | ||
$!code(| @!args, action => $.action ); | ||
} elsif $!controller { | ||
$!code(| @!args, controller => $.controller ); | ||
} else { | ||
$!code(| @!args ); | ||
} | ||
} | ||
|
||
method is_complete { | ||
return ?( @!pattern && $!code ); | ||
} | ||
|
||
method clear { | ||
@!args = (); | ||
$!controller = undef; | ||
$!action = undef; | ||
} | ||
|
||
# vim:ft=perl6 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
use v6; | ||
|
||
use Test; | ||
plan 8; | ||
|
||
use Dispatcher; | ||
ok(1,'We use Dispatcher and we are still alive'); | ||
|
||
use Dispatcher::Rule; | ||
ok(1,'We use Dispatcher::Rule and we are still alive'); | ||
|
||
my $d = Dispatcher.new; | ||
|
||
dies_ok( { $d.add: Dispatcher::Rule.new }, | ||
'.add adds only complete Rule objects' ); | ||
|
||
$d.add: Dispatcher::Rule.new( :pattern(['']), code => { "Krevedko" } ); | ||
|
||
is( $d.dispatch(['']), | ||
'Krevedko', | ||
"Pattern ['']" | ||
); | ||
|
||
ok( $d.add( ['foo', 'bar'], { "Yay" } ), | ||
'.add(@pattern, $code) -- shortcut for fast add Rule object' ); | ||
|
||
nok( $d.dispatch(['foo']), | ||
'Dispatcher return False if can`t find matched Rule and do not have default' ); | ||
|
||
|
||
is( $d.dispatch(['foo', 'bar']), | ||
"Yay", | ||
"Dispatch to Rule ['foo', 'bar'])" | ||
); | ||
|
||
$d.default = { "Woow" }; | ||
|
||
is( $d.dispatch(['foo', 'bar', 'baz']), | ||
"Woow", | ||
'Dispatch to default, when have no matched Rule' | ||
); | ||
|
||
# vim:ft=perl6 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
use v6; | ||
|
||
use Test; | ||
plan 5; | ||
|
||
use Dispatcher; | ||
|
||
my $d = Dispatcher.new; | ||
|
||
my @rules = | ||
['foo'], { "A" }, | ||
[/\d+/], { "B" }, | ||
['foo', 'bar'], { "C" }, | ||
['her'|'boo'], { "D" }; | ||
|
||
is($d.add(@rules), 4, "add list of rules, get the number added back"); | ||
|
||
is($d.dispatch(['foo']), "A", "Dispatch rule ['foo']"); | ||
is($d.dispatch(['123']), "B", "Dispatch rule /\\d+/"); | ||
is($d.dispatch(['foo', 'bar']), "C", "Dispatch ['foo', 'bar']"); | ||
is($d.dispatch(['boo']), "D", "Dispatch ['boo']"); | ||
|
||
# vim:ft=perl6 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
use v6; | ||
use Test; | ||
plan 5; | ||
|
||
use Dispatcher; | ||
|
||
my $d = Dispatcher.new( default => { "default" } ); | ||
|
||
$d.add( | ||
[ | ||
[*,], { $^a }, | ||
[*,*], { $^a + $^b }, | ||
['foo', *], { 'foo/' ~ $^a }, | ||
['foo', *, *], { 'foo:' ~ $^a - $^b }, | ||
['foo', *, 'bar'], { $^b }, | ||
] | ||
); | ||
|
||
is( $d.dispatch([42]), 42, 'Pattern *' ); | ||
is( $d.dispatch([1, 2]), 3, 'Pattern */* ' ); | ||
is( $d.dispatch(['foo', '5']), "foo/5", 'Pattern foo/*' ); | ||
is( $d.dispatch(['foo', '5', 1]), "foo:4", 'Pattern foo/*/*' ); | ||
is( $d.dispatch(['foo', 'baz', 'bar']), "baz", 'Pattern foo/*/bar' ); | ||
|
||
|
||
# vim:ft=perl6 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
use v6; | ||
|
||
use Test; | ||
plan 6; | ||
|
||
use Dispatcher; | ||
my $d = Dispatcher.new; | ||
$d.add: [ | ||
['foo', /^ \d+ $/], { $^d }, | ||
[/^ \w+ $/], { "Yep!" if $^w.WHAT eq 'Match' }, | ||
['foo', / \d+ /], { $^d + 10 }, | ||
['foo', / \d+ /, 'bar' ], { $^d + 1 }, | ||
['summ', / \d+ /, / \d+ / ], { $^a + $^b }, | ||
['summ', / \w+ /, 1|2 ], { $^a ~ "oo" } | ||
]; | ||
|
||
|
||
is( $d.dispatch(['foo']), | ||
'Yep!', | ||
"Pattern with regex \w+, put Match in args" | ||
); | ||
|
||
is( $d.dispatch(['foo', '50']), | ||
'60', | ||
"Dispatch ['foo', '50'] to last matched Rule" | ||
); | ||
|
||
is( $d.dispatch(['foo', 'a50z']), | ||
'60', | ||
'Pattern with regex \d, put Match in args' | ||
); | ||
|
||
is( $d.dispatch(['foo', 'item4', 'bar']), | ||
'5', | ||
'Pattern with regexp in the middle (foo/\d+/bar)' | ||
); | ||
|
||
is( $d.dispatch(['summ', '2', '3']), | ||
'5', | ||
'Pattern with two regexs' | ||
); | ||
|
||
is( $d.dispatch(['summ', 'Z', '2']), | ||
'Zoo', | ||
'Pattern with regexp and junction' | ||
); | ||
|
||
# vim:ft=perl6 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
use v6; | ||
|
||
use Test; | ||
plan 4; | ||
|
||
use Dispatcher; | ||
my $d = Dispatcher.new; | ||
|
||
$d.add: [ | ||
['foo'|'bar'], { 'First' }, | ||
['foo', 'a'|'b'], { 'Second' }, | ||
]; | ||
|
||
is( $d.dispatch(['foo']), | ||
'First', | ||
'Pattern with Junction (foo|bar) foo' | ||
); | ||
|
||
is( $d.dispatch(['bar']), | ||
'First', | ||
'Pattern with Junction (foo|bar) bar' | ||
); | ||
|
||
is( $d.dispatch(['foo', 'a']), | ||
'Second', | ||
'Pattern with Junction (foo/a|b) a' | ||
); | ||
|
||
is( $d.dispatch(['foo', 'b']), | ||
'Second', | ||
'Pattern with Junction (foo/a|b) b' | ||
); | ||
|
||
# vim:ft=perl6 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
use v6; | ||
|
||
use Test; | ||
plan 4; | ||
|
||
use Dispatcher; | ||
my $d = Dispatcher.new; | ||
|
||
$d.add: [ | ||
[:controller(*), :action(*) ], { 'c:' ~ $:controller ~ ' a:' ~ $:action }, | ||
[:controller(*), / \d / ], { $:controller ~ '/' ~ $^a }, | ||
[:controller(*), *, * ], { my $c = $:controller; use "$c"; is($^a, $^b, 'Test within Rule') }, | ||
]; | ||
|
||
is( $d.dispatch(['one', 5]), | ||
'one/5', | ||
'Pattern set controller' | ||
); | ||
|
||
is( $d.dispatch(['one', 'two']), | ||
'c:one a:two', | ||
'Pattern set controller and action' | ||
); | ||
|
||
is( $d.dispatch(['Test', 3, 3]), | ||
1, | ||
'Pattern set controller and action' | ||
); | ||
|
||
# vim:ft=perl6 |