mustermann 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +9 -6
- data/README.md +247 -10
- data/lib/mustermann.rb +13 -5
- data/lib/mustermann/ast/expander.rb +15 -0
- data/lib/mustermann/ast/pattern.rb +2 -3
- data/lib/mustermann/expander.rb +39 -4
- data/lib/mustermann/mapper.rb +94 -0
- data/lib/mustermann/pattern.rb +3 -3
- data/lib/mustermann/regular.rb +26 -0
- data/lib/mustermann/router/rack.rb +2 -2
- data/lib/mustermann/router/simple.rb +1 -1
- data/lib/mustermann/sinatra.rb +1 -1
- data/lib/mustermann/to_pattern.rb +45 -0
- data/lib/mustermann/version.rb +1 -1
- data/mustermann.gemspec +3 -1
- data/spec/expander_spec.rb +28 -0
- data/spec/mapper_spec.rb +83 -0
- data/spec/mustermann_spec.rb +30 -10
- data/spec/pattern_spec.rb +27 -4
- data/spec/regexp_based_spec.rb +1 -1
- data/spec/regular_spec.rb +36 -0
- data/spec/router/rack_spec.rb +1 -1
- data/spec/router/simple_spec.rb +9 -7
- data/spec/shell_spec.rb +1 -1
- data/spec/simple_match_spec.rb +1 -1
- data/spec/sinatra_spec.rb +13 -0
- data/spec/support/env.rb +11 -1
- data/spec/support/expand_matcher.rb +2 -2
- data/spec/support/match_matcher.rb +2 -2
- data/spec/support/pattern.rb +6 -2
- data/spec/to_pattern_spec.rb +20 -0
- metadata +64 -28
- data/lib/mustermann/equality_map.rb +0 -46
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c4814f10c7f9b66968a8eaadb89f2eeacb328096
|
4
|
+
data.tar.gz: 69ae8b9fd3dfd3d50f0301ae10e05f168c98e5fe
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 44ad20b4f6e4324732e3d6734438b4400aacbab936fedb197aee75dcd9d9522797e1c1244ff86ebc78d7855e84b8b53e440acaa9785c13e7a2c33170850b0fba
|
7
|
+
data.tar.gz: c8b2bf771c04af78b64045fe61c6188cba366472242f72286802ea7737f60d8fb0728cc946fbaadad07e1502a829f7bb94b815d7501c1b5e808bf5559eb1e360
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,11 @@
|
|
1
1
|
# The Amazing Mustermann
|
2
2
|
|
3
|
-
[](https://travis-ci.org/rkh/mustermann) [](https://coveralls.io/r/rkh/mustermann) [](https://codeclimate.com/github/rkh/mustermann) [](https://gemnasium.com/rkh/mustermann) [](https://rubygems.org/gems/mustermann)
|
4
|
+
[](http://inch-ci.org/github/rkh/mustermann)
|
5
|
+
[](http://rubydoc.info/gems/mustermann/frames)
|
6
|
+
[](http://rkh.mit-license.org)
|
7
|
+
[](http://img.shields.io)
|
8
|
+
|
4
9
|
|
5
10
|
*Make sure you view the correct docs: [latest release](http://rubydoc.info/gems/mustermann/frames), [master](http://rubydoc.info/github/rkh/mustermann/master/frames).*
|
6
11
|
|
@@ -82,6 +87,16 @@ The available types are:
|
|
82
87
|
<a href="#pattern_expanding">Expanding</a>
|
83
88
|
</td>
|
84
89
|
</tr>
|
90
|
+
<tr>
|
91
|
+
<th><a href="#regexp"><tt>regexp</tt></a></th>
|
92
|
+
<td>Regular expressions as implemented by Ruby</td>
|
93
|
+
<td><tt>/(?<slug>.*)</tt></td>
|
94
|
+
<td>
|
95
|
+
<a href="#ignore_unknown_options"><tt>ignore_unknown_options</tt></a>,
|
96
|
+
<a href="#uri_decode"><tt>uri_decode</tt></a>
|
97
|
+
</td>
|
98
|
+
<td></td>
|
99
|
+
</tr>
|
85
100
|
<tr>
|
86
101
|
<th><a href="#shell"><tt>shell</tt></th>
|
87
102
|
<td>Unix style patterns</td>
|
@@ -346,6 +361,50 @@ expander = Mustermann::Expander.new("/:slug", additional_values: :append)
|
|
346
361
|
expander.expand(slug: "foo", value: "bar") # => "/foo?value=bar"
|
347
362
|
```
|
348
363
|
|
364
|
+
## Duck Typing
|
365
|
+
|
366
|
+
All methods converting string input to pattern objects will also accept any arbitrary object that implements `to_pattern`:
|
367
|
+
|
368
|
+
``` ruby
|
369
|
+
require 'mustermann'
|
370
|
+
|
371
|
+
class MyObject
|
372
|
+
def to_pattern(**options)
|
373
|
+
Mustermann.new("/foo", **options)
|
374
|
+
end
|
375
|
+
end
|
376
|
+
|
377
|
+
object = MyObject.new
|
378
|
+
Mustermann.new(object, type: :rails) # => #<Mustermann::Rails:"/foo">
|
379
|
+
```
|
380
|
+
|
381
|
+
It might also be that you want to call `to_pattern` yourself instead of `Mustermann.new`. You can load `mustermann/to_pattern` to implement this method for strings, regular expressions and pattern objects:
|
382
|
+
|
383
|
+
``` ruby
|
384
|
+
require 'mustermann/to_pattern'
|
385
|
+
|
386
|
+
"/foo".to_pattern # => #<Mustermann::Sinatra:"/foo">
|
387
|
+
"/foo".to_pattern(type: :rails) # => #<Mustermann::Rails:"/foo">
|
388
|
+
%r{/foo}.to_pattern # => #<Mustermann::Regular:"\\/foo">
|
389
|
+
"/foo".to_pattern.to_pattern # => #<Mustermann::Sinatra:"/foo">
|
390
|
+
```
|
391
|
+
|
392
|
+
You can also use the `Mustermann::ToPattern` mixin to easily add `to_pattern` to your own objects:
|
393
|
+
|
394
|
+
``` ruby
|
395
|
+
require 'mustermann/to_pattern'
|
396
|
+
|
397
|
+
class MyObject
|
398
|
+
include Mustermann::ToPattern
|
399
|
+
|
400
|
+
def to_s
|
401
|
+
"/foo"
|
402
|
+
end
|
403
|
+
end
|
404
|
+
|
405
|
+
MyObject.new.to_pattern # => #<Mustermann::Sinatra:"/foo">
|
406
|
+
```
|
407
|
+
|
349
408
|
## Partial Loading and Thread Safety
|
350
409
|
|
351
410
|
Pattern objects are generally assumed to be thread-safe. You can easily match strings against the same pattern object concurrently.
|
@@ -481,7 +540,17 @@ By setting `ignore_unknown_options` to `true`, it will happily ignore the option
|
|
481
540
|
|
482
541
|
### `identity`
|
483
542
|
|
484
|
-
|
543
|
+
Identity patterns are strings that have to match the input exactly.
|
544
|
+
|
545
|
+
``` ruby
|
546
|
+
require 'mustermann'
|
547
|
+
|
548
|
+
pattern = Mustermann.new('/:example', type: :identity)
|
549
|
+
pattern === "/foo.bar" # => false
|
550
|
+
pattern === "/:example" # => true
|
551
|
+
pattern.params("/foo.bar") # => nil
|
552
|
+
pattern.params("/:example") # => {}
|
553
|
+
```
|
485
554
|
|
486
555
|
<table>
|
487
556
|
<thead>
|
@@ -502,6 +571,28 @@ Patterns that are no real patterns, just string matching.
|
|
502
571
|
|
503
572
|
Patterns with the syntax used in Rails route definitions.
|
504
573
|
|
574
|
+
``` ruby
|
575
|
+
require 'mustermann'
|
576
|
+
|
577
|
+
pattern = Mustermann.new('/:example', type: :rails)
|
578
|
+
pattern === "/foo.bar" # => true
|
579
|
+
pattern === "/foo/bar" # => false
|
580
|
+
pattern.params("/foo.bar") # => { "example" => "foo.bar" }
|
581
|
+
pattern.params("/foo/bar") # => nil
|
582
|
+
|
583
|
+
pattern = Mustermann.new('/:example(/:optional)', type: :rails)
|
584
|
+
pattern === "/foo.bar" # => true
|
585
|
+
pattern === "/foo/bar" # => true
|
586
|
+
pattern.params("/foo.bar") # => { "example" => "foo.bar", "optional" => nil }
|
587
|
+
pattern.params("/foo/bar") # => { "example" => "foo", "optional" => "bar" }
|
588
|
+
|
589
|
+
pattern = Mustermann.new('/*example', type: :rails)
|
590
|
+
pattern === "/foo.bar" # => true
|
591
|
+
pattern === "/foo/bar" # => true
|
592
|
+
pattern.params("/foo.bar") # => { "example" => "foo.bar" }
|
593
|
+
pattern.params("/foo/bar") # => { "example" => "foo/bar" }
|
594
|
+
```
|
595
|
+
|
505
596
|
<table>
|
506
597
|
<thead>
|
507
598
|
<tr>
|
@@ -540,10 +631,64 @@ Patterns with the syntax used in Rails route definitions.
|
|
540
631
|
</tbody>
|
541
632
|
</table>
|
542
633
|
|
634
|
+
### `regexp`
|
635
|
+
|
636
|
+
Regular expression patterns, as used implemented by Ruby. Do not include characters for matching beginning or end of string/line.
|
637
|
+
This pattern type is also known as `regular` and the pattern class is `Mustermann::Regular` (located in `mustermann/regular`).
|
638
|
+
|
639
|
+
``` ruby
|
640
|
+
require 'mustermann'
|
641
|
+
|
642
|
+
pattern = Mustermann.new('/(?<example>.*)', type: :regexp)
|
643
|
+
pattern === "/foo.bar" # => true
|
644
|
+
pattern === "/foo/bar" # => true
|
645
|
+
pattern.params("/foo.bar") # => { "example" => "foo.bar" }
|
646
|
+
pattern.params("/foo/bar") # => { "example" => "foo/bar" }
|
647
|
+
```
|
648
|
+
|
649
|
+
<table>
|
650
|
+
<thead>
|
651
|
+
<tr>
|
652
|
+
<th>Syntax Element</th>
|
653
|
+
<th>Description</th>
|
654
|
+
</tr>
|
655
|
+
</thead>
|
656
|
+
<tbody>
|
657
|
+
<tr>
|
658
|
+
<td><i>any string</i></td>
|
659
|
+
<td>Interpreted as regular expression.</td>
|
660
|
+
</tr>
|
661
|
+
</tbody>
|
662
|
+
</table>
|
663
|
+
|
664
|
+
It is also possible to turn a proper Regexp instance into a pattern object by passing it to `Mustermann.new`:
|
665
|
+
|
666
|
+
``` ruby
|
667
|
+
require 'mustermann'
|
668
|
+
Mustermann.new(/(?<example>.*)/).params("input") # => { "example" => "input" }
|
669
|
+
```
|
670
|
+
|
543
671
|
### `shell`
|
544
672
|
|
545
673
|
Shell patterns, as used in Bash or with `Dir.glob`.
|
546
674
|
|
675
|
+
``` ruby
|
676
|
+
require 'mustermann'
|
677
|
+
|
678
|
+
pattern = Mustermann.new('/*', type: :shell)
|
679
|
+
pattern === "/foo.bar" # => true
|
680
|
+
pattern === "/foo/bar" # => false
|
681
|
+
|
682
|
+
pattern = Mustermann.new('/**/*', type: :shell)
|
683
|
+
pattern === "/foo.bar" # => true
|
684
|
+
pattern === "/foo/bar" # => true
|
685
|
+
|
686
|
+
pattern = Mustermann.new('/{foo,bar}', type: :shell)
|
687
|
+
pattern === "/foo" # => true
|
688
|
+
pattern === "/bar" # => true
|
689
|
+
pattern === "/baz" # => false
|
690
|
+
```
|
691
|
+
|
547
692
|
<table>
|
548
693
|
<thead>
|
549
694
|
<tr>
|
@@ -581,7 +726,29 @@ Shell patterns, as used in Bash or with `Dir.glob`.
|
|
581
726
|
|
582
727
|
### `simple`
|
583
728
|
|
584
|
-
Patterns as used by Sinatra 1.3. Useful for porting an application that relies on this behavior to a later Sinatra version and to make sure [Sinatra 2.0](#sinatra) patterns do not decrease performance.
|
729
|
+
Patterns as used by Sinatra 1.3. Useful for porting an application that relies on this behavior to a later Sinatra version and to make sure [Sinatra 2.0](#sinatra) patterns do not decrease performance. Simple patterns internally use the same code older Sinatra versions used for compiling the pattern. Error messages for broken patterns will therefore not be as informative as for other pattern implementations.
|
730
|
+
|
731
|
+
``` ruby
|
732
|
+
require 'mustermann'
|
733
|
+
|
734
|
+
pattern = Mustermann.new('/:example', type: :simple)
|
735
|
+
pattern === "/foo.bar" # => true
|
736
|
+
pattern === "/foo/bar" # => false
|
737
|
+
pattern.params("/foo.bar") # => { "example" => "foo.bar" }
|
738
|
+
pattern.params("/foo/bar") # => nil
|
739
|
+
|
740
|
+
pattern = Mustermann.new('/:example/?:optional?', type: :simple)
|
741
|
+
pattern === "/foo.bar" # => true
|
742
|
+
pattern === "/foo/bar" # => true
|
743
|
+
pattern.params("/foo.bar") # => { "example" => "foo.bar", "optional" => nil }
|
744
|
+
pattern.params("/foo/bar") # => { "example" => "foo", "optional" => "bar" }
|
745
|
+
|
746
|
+
pattern = Mustermann.new('/*', type: :simple)
|
747
|
+
pattern === "/foo.bar" # => true
|
748
|
+
pattern === "/foo/bar" # => true
|
749
|
+
pattern.params("/foo.bar") # => { "splat" => ["foo.bar"] }
|
750
|
+
pattern.params("/foo/bar") # => { "splat" => ["foo/bar"] }
|
751
|
+
```
|
585
752
|
|
586
753
|
<table>
|
587
754
|
<thead>
|
@@ -629,6 +796,40 @@ Patterns as used by Sinatra 1.3. Useful for porting an application that relies o
|
|
629
796
|
|
630
797
|
Sinatra 2.0 style patterns. The default used by Mustermann.
|
631
798
|
|
799
|
+
``` ruby
|
800
|
+
require 'mustermann'
|
801
|
+
|
802
|
+
pattern = Mustermann.new('/:example')
|
803
|
+
pattern === "/foo.bar" # => true
|
804
|
+
pattern === "/foo/bar" # => false
|
805
|
+
pattern.params("/foo.bar") # => { "example" => "foo.bar" }
|
806
|
+
pattern.params("/foo/bar") # => nil
|
807
|
+
|
808
|
+
pattern = Mustermann.new('/\:example')
|
809
|
+
pattern === "/foo.bar" # => false
|
810
|
+
pattern === "/:example" # => true
|
811
|
+
pattern.params("/foo.bar") # => nil
|
812
|
+
pattern.params("/:example") # => {}
|
813
|
+
|
814
|
+
pattern = Mustermann.new('/:example(/:optional)?')
|
815
|
+
pattern === "/foo.bar" # => true
|
816
|
+
pattern === "/foo/bar" # => true
|
817
|
+
pattern.params("/foo.bar") # => { "example" => "foo.bar", "optional" => nil }
|
818
|
+
pattern.params("/foo/bar") # => { "example" => "foo", "optional" => "bar" }
|
819
|
+
|
820
|
+
pattern = Mustermann.new('/*')
|
821
|
+
pattern === "/foo.bar" # => true
|
822
|
+
pattern === "/foo/bar" # => true
|
823
|
+
pattern.params("/foo.bar") # => { "splat" => ["foo.bar"] }
|
824
|
+
pattern.params("/foo/bar") # => { "splat" => ["foo/bar"] }
|
825
|
+
|
826
|
+
pattern = Mustermann.new('/*example')
|
827
|
+
pattern === "/foo.bar" # => true
|
828
|
+
pattern === "/foo/bar" # => true
|
829
|
+
pattern.params("/foo.bar") # => { "example" => "foo.bar" }
|
830
|
+
pattern.params("/foo/bar") # => { "example" => "foo/bar" }
|
831
|
+
```
|
832
|
+
|
632
833
|
<table>
|
633
834
|
<thead>
|
634
835
|
<tr>
|
@@ -644,6 +845,12 @@ Sinatra 2.0 style patterns. The default used by Mustermann.
|
|
644
845
|
Capture behavior can be modified with <a href="#capture"><tt>capture</tt></a> and <a href="#greedy"><tt>greedy</tt></a> option.
|
645
846
|
</td>
|
646
847
|
</tr>
|
848
|
+
<tr>
|
849
|
+
<td><b>*</b><i>name</i></td>
|
850
|
+
<td>
|
851
|
+
Captures anything in a non-greedy fashion. Capture is named <i>name</i>.
|
852
|
+
</td>
|
853
|
+
</tr>
|
647
854
|
<tr>
|
648
855
|
<td><b>*</b></td>
|
649
856
|
<td>
|
@@ -685,6 +892,19 @@ Parses fully expanded URI templates as specified by [RFC 6570](http://tools.ietf
|
|
685
892
|
|
686
893
|
Note that it differs from URI templates in that it takes the unescaped version of special character instead of the escaped version.
|
687
894
|
|
895
|
+
``` ruby
|
896
|
+
require 'mustermann'
|
897
|
+
|
898
|
+
pattern = Mustermann.new('/{example}', type: :template)
|
899
|
+
pattern === "/foo.bar" # => true
|
900
|
+
pattern === "/foo/bar" # => false
|
901
|
+
pattern.params("/foo.bar") # => { "example" => "foo.bar" }
|
902
|
+
pattern.params("/foo/bar") # => nil
|
903
|
+
|
904
|
+
pattern = Mustermann.new("{/segments*}/{page}{.ext,cmpr:2}", type: :template)
|
905
|
+
pattern.params("/a/b/c.tar.gz") # => {"segments"=>["a","b"], "page"=>"c", "ext"=>"tar", "cmpr"=>"gz"}
|
906
|
+
```
|
907
|
+
|
688
908
|
<table>
|
689
909
|
<thead>
|
690
910
|
<tr>
|
@@ -718,11 +938,6 @@ The operators `+` and `#` will always match non-greedy, whereas all other operat
|
|
718
938
|
All modifiers and operators are supported. However, it does not parse lists as single values without the *explode* modifier (aka *star*).
|
719
939
|
Parametric operators (`;`, `?` and `&`) currently only match parameters in given order.
|
720
940
|
|
721
|
-
``` ruby
|
722
|
-
pattern = Mustermann.new("{/segments*}/{page}{.ext,cmpr:2}", type: :template)
|
723
|
-
pattern.params("/a/b/c.tar.gz") # => {"segments"=>["a","b"], "page"=>"c", "ext"=>"tar", "cmpr"=>"gz"}
|
724
|
-
```
|
725
|
-
|
726
941
|
Please keep the following in mind:
|
727
942
|
|
728
943
|
> "Some URI Templates can be used in reverse for the purpose of variable matching: comparing the template to a fully formed URI in order to extract the variable parts from that URI and assign them to the named variables. Variable matching only works well if the template expressions are delimited by the beginning or end of the URI or by characters that cannot be part of the expansion, such as reserved characters surrounding a simple string expression. In general, regular expression languages are better suited for variable matching."
|
@@ -733,6 +948,19 @@ you should set `uri_decode` to `false` in order to conform with the specificatio
|
|
733
948
|
|
734
949
|
If you are looking for an alternative implementation that also supports expanding, check out [addressable](http://addressable.rubyforge.org/).
|
735
950
|
|
951
|
+
## Mapper
|
952
|
+
|
953
|
+
You can use a mapper to transform strings according to two or more mappings:
|
954
|
+
|
955
|
+
``` ruby
|
956
|
+
require 'mustermann/mapper'
|
957
|
+
|
958
|
+
mapper = Mustermann::Mapper.new("/:page(.:format)?" => ["/:page/view.:format", "/:page/view.html"])
|
959
|
+
mapper['/foo'] # => "/foo/view.html"
|
960
|
+
mapper['/foo.xml'] # => "/foo/view.xml"
|
961
|
+
mapper['/foo/bar'] # => "/foo/bar"
|
962
|
+
```
|
963
|
+
|
736
964
|
## Routers
|
737
965
|
|
738
966
|
Mustermann comes with basic router implementations that will call certain callbacks depending on the input.
|
@@ -757,7 +985,7 @@ This is not a full replacement for Rails, Sinatra, Cuba, etc, as it only cares a
|
|
757
985
|
``` ruby
|
758
986
|
require 'mustermann/router/rack'
|
759
987
|
|
760
|
-
router = Mustermann::Router::Rack do
|
988
|
+
router = Mustermann::Router::Rack.new do
|
761
989
|
on '/' do |env|
|
762
990
|
[200, {'Content-Type' => 'text/plain'}, ['Hello World!']]
|
763
991
|
end
|
@@ -795,6 +1023,16 @@ As there has been no stable release yet, the API might still change, though I co
|
|
795
1023
|
|
796
1024
|
### Development Releases
|
797
1025
|
|
1026
|
+
* **Mustermann 0.3.0** (2014-08-18)
|
1027
|
+
* More Infos:
|
1028
|
+
[RubyGems.org](http://rubygems.org/gems/mustermann/versions/0.3.0),
|
1029
|
+
[RubyDoc.info](http://rubydoc.info/gems/mustermann/0.3.0/frames),
|
1030
|
+
[GitHub.com](https://github.com/rkh/mustermann/tree/v0.3.0)
|
1031
|
+
* Add `regexp` pattern.
|
1032
|
+
* Add named splats to Sinatra patterns.
|
1033
|
+
* Add `Mustermann::Mapper`.
|
1034
|
+
* Improve duck typing support.
|
1035
|
+
* Improve documentation.
|
798
1036
|
* **Mustermann 0.2.0** (2013-08-24)
|
799
1037
|
* More Infos:
|
800
1038
|
[RubyGems.org](http://rubygems.org/gems/mustermann/versions/0.2.0),
|
@@ -832,6 +1070,5 @@ As there has been no stable release yet, the API might still change, though I co
|
|
832
1070
|
|
833
1071
|
### Upcoming Releases
|
834
1072
|
|
835
|
-
* **Mustermann 0.3.0** (next release with new features)
|
836
1073
|
* **Mustermann 1.0.0** (before Sinatra 2.0)
|
837
1074
|
* First stable release.
|
data/lib/mustermann.rb
CHANGED
@@ -1,15 +1,22 @@
|
|
1
|
+
require 'mustermann/pattern'
|
2
|
+
|
1
3
|
# Namespace and main entry point for the Mustermann library.
|
2
4
|
#
|
3
5
|
# Under normal circumstances the only external API entry point you should be using is {Mustermann.new}.
|
4
6
|
module Mustermann
|
5
|
-
# @param [String]
|
7
|
+
# @param [String, Pattern, Regexp, #to_pattern] input The representation of the new pattern
|
6
8
|
# @param [Hash] options The options hash
|
7
9
|
# @return [Mustermann::Pattern] pattern corresponding to string.
|
8
10
|
# @raise (see [])
|
9
11
|
# @raise (see Mustermann::Pattern.new)
|
10
12
|
# @see file:README.md#Types_and_Options "Types and Options" in the README
|
11
|
-
def self.new(
|
12
|
-
|
13
|
+
def self.new(input, type: :sinatra, **options)
|
14
|
+
case input
|
15
|
+
when Pattern then input
|
16
|
+
when Regexp then self[:regexp].new(input, **options)
|
17
|
+
when String then self[type].new(input, **options)
|
18
|
+
else input.to_pattern(type: type, **options)
|
19
|
+
end
|
13
20
|
end
|
14
21
|
|
15
22
|
# Maps a type to its factory.
|
@@ -27,9 +34,9 @@ module Mustermann
|
|
27
34
|
end
|
28
35
|
|
29
36
|
# @!visibility private
|
30
|
-
def self.register(
|
37
|
+
def self.register(*identifiers, constant: identifiers.first.to_s.capitalize, load: "mustermann/#{identifiers.first}")
|
31
38
|
@register ||= {}
|
32
|
-
@register[
|
39
|
+
identifiers.each { |i| @register[i] = [constant, load] }
|
33
40
|
@register
|
34
41
|
end
|
35
42
|
|
@@ -42,6 +49,7 @@ module Mustermann
|
|
42
49
|
|
43
50
|
register :identity
|
44
51
|
register :rails
|
52
|
+
register :regular, :regexp
|
45
53
|
register :shell
|
46
54
|
register :simple
|
47
55
|
register :sinatra
|
@@ -59,10 +59,17 @@ module Mustermann
|
|
59
59
|
@mappings ||= {}
|
60
60
|
end
|
61
61
|
|
62
|
+
# all the known keys
|
63
|
+
# @!visibility private
|
64
|
+
def keys
|
65
|
+
@keys ||= []
|
66
|
+
end
|
67
|
+
|
62
68
|
# add a tree for expansion
|
63
69
|
# @!visibility private
|
64
70
|
def add(ast)
|
65
71
|
translate(ast).each do |keys, pattern, filter|
|
72
|
+
self.keys.concat(keys).uniq!
|
66
73
|
mappings[keys.uniq.sort] ||= [keys, pattern, filter]
|
67
74
|
end
|
68
75
|
end
|
@@ -81,6 +88,14 @@ module Mustermann
|
|
81
88
|
pattern % values.values_at(*keys)
|
82
89
|
end
|
83
90
|
|
91
|
+
# @see Mustermann::Pattern#expandable?
|
92
|
+
# @!visibility private
|
93
|
+
def expandable?(values)
|
94
|
+
values = values.keys if values.respond_to? :keys
|
95
|
+
values = values.sort if values.respond_to? :sort
|
96
|
+
mappings.include? values
|
97
|
+
end
|
98
|
+
|
84
99
|
# @see Mustermann::Expander#with_rest
|
85
100
|
# @!visibility private
|
86
101
|
def expandable_keys(keys)
|