mustermann-contrib 3.1.0 → 4.0.0.alpha

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d3990aa843c8c57b75fc5e7a5a8fa0b0d56f6f46c6a8e4ad8a5b408066b3ee96
4
- data.tar.gz: 82b5f3729b4ae440bb94be9117558bd83dbead5b07599254dc3255104cab3f5e
3
+ metadata.gz: ba766f2be34c126a5c87154b9e9ff3e6d5f5e2f8080f2b29a30850f5634fa91d
4
+ data.tar.gz: 3a62549ac2e49145dca087f9b082fb1957d50293fadb3ef5c84911cdb43b80ee
5
5
  SHA512:
6
- metadata.gz: bd18842741789080329166170db2b904af298f2bd80e797e259bb02740aab45ea313f3009f0570079db11cf0d3728b38fb8833c94004b52f43123a27835a3035
7
- data.tar.gz: 7d7a909d1970370e86097380bbd0ca47c04e2d34ef2e41ed10d2da1ce60a21976e3b7a814b2d549cd4cbdcee6f6ba3398ba1922a524c7e8d87b0d88336c1c8b3
6
+ metadata.gz: acc416d7cbeddec35cad710634f66a77dc9adbc89a80d493fd6b6e99336c266dca4bc6ee2a9d09fdbf2e358fa6666303016750bd455c620f06381a5d55cf2eb3
7
+ data.tar.gz: 8bccefca2caf7829bf3aa2d8a57fcadf7bed1e4a0ae0d17142a241ba1ffa94d0fd63f01a1cf44f6d2816a446ad048090e20bfe85fd26ff7211f5725170ea0518
data/LICENSE CHANGED
@@ -1,5 +1,4 @@
1
- Copyright (c) 2013-2017 Konstantin Haase
2
- Copyright (c) 2016-2017 Zachary Scott
1
+ Copyright (c) Konstantin Haase
3
2
 
4
3
  Permission is hereby granted, free of charge, to any person
5
4
  obtaining a copy of this software and associated documentation
data/README.md CHANGED
@@ -27,177 +27,13 @@ end
27
27
  <a name="-mustermann-cake"></a>
28
28
  # CakePHP Syntax for Mustermann
29
29
 
30
- This gem implements the `cake` pattern type for Mustermann. It is compatible with [CakePHP](http://cakephp.org/) 2.x and 3.x.
31
-
32
- ## Overview
33
-
34
- **Supported options:**
35
- `capture`, `except`, `greedy`, `space_matches_plus`, `uri_decode`, and `ignore_unknown_options`.
36
-
37
- **External documentation:**
38
- [CakePHP 2.0 Routing](http://book.cakephp.org/2.0/en/development/routing.html),
39
- [CakePHP 3.0 Routing](http://book.cakephp.org/3.0/en/development/routing.html)
40
-
41
- CakePHP patterns feature captures and unnamed splats. Captures are prefixed with a colon and splats are either a single asterisk (parsing segments into an array) or a double asterisk (parsing segments as a single string).
42
-
43
- ``` ruby
44
- require 'mustermann/cake'
45
-
46
- Mustermann.new('/:name/*', type: :cake).params('/a/b/c') # => { name: 'a', splat: ['b', 'c'] }
47
- Mustermann.new('/:name/**', type: :cake).params('/a/b/c') # => { name: 'a', splat: 'b/c' }
48
-
49
- pattern = Mustermann.new('/:name')
50
-
51
- pattern.respond_to? :expand # => true
52
- pattern.expand(name: 'foo') # => '/foo'
53
-
54
- pattern.respond_to? :to_templates # => true
55
- pattern.to_templates # => ['/{name}']
56
- ```
57
-
58
- ## Syntax
59
-
60
- <table>
61
- <thead>
62
- <tr>
63
- <th>Syntax Element</th>
64
- <th>Description</th>
65
- </tr>
66
- </thead>
67
- <tbody>
68
- <tr>
69
- <td><b>:</b><i>name</i></td>
70
- <td>
71
- Captures anything but a forward slash in a semi-greedy fashion. Capture is named <i>name</i>.
72
- Capture behavior can be modified with <tt>capture</tt> and <tt>greedy</tt> option.
73
- </td>
74
- </tr>
75
- <tr>
76
- <td><b>*</b></td>
77
- <td>
78
- Captures anything in a non-greedy fashion. Capture is named splat.
79
- It is always an array of captures, as you can use it more than once in a pattern.
80
- </td>
81
- </tr>
82
- <tr>
83
- <td><b>**</b></td>
84
- <td>
85
- Captures anything in a non-greedy fashion. Capture is named splat.
86
- It is always an array of captures, as you can use it more than once in a pattern.
87
- The value matching a single <tt>**</tt> will be split at slashes when parsed into <tt>params</tt>.
88
- </td>
89
- </tr>
90
- <tr>
91
- <td><b>/</b></td>
92
- <td>
93
- Matches forward slash. Does not match URI encoded version of forward slash.
94
- </td>
95
- </tr>
96
- <tr>
97
- <td><i>any other character</i></td>
98
- <td>Matches exactly that character or a URI encoded version of it.</td>
99
- </tr>
100
- </tbody>
101
- </table>
30
+ See [docs/patterns/cake.md](../docs/patterns/cake.md).
102
31
 
103
32
 
104
33
  <a name="-mustermann-express"></a>
105
34
  # Express Syntax for Mustermann
106
35
 
107
- This gem implements the `express` pattern type for Mustermann. It is compatible with [Express](http://expressjs.com/) and [pillar.js](https://pillarjs.github.io/).
108
-
109
- ## Overview
110
-
111
- **Supported options:**
112
- `capture`, `except`, `greedy`, `space_matches_plus`, `uri_decode`, and `ignore_unknown_options`.
113
-
114
- **External documentation:**
115
- [path-to-regexp](https://github.com/pillarjs/path-to-regexp#path-to-regexp),
116
- [live demo](http://forbeslindesay.github.io/express-route-tester/)
117
-
118
- Express patterns feature named captures (with repetition support via suffixes) that start with a colon and can have an optional regular expression constraint or unnamed captures that require a constraint.
119
-
120
- ``` ruby
121
- require 'mustermann/express'
122
-
123
- Mustermann.new('/:name/:rest+', type: :express).params('/a/b/c') # => { name: 'a', rest: 'b/c' }
124
-
125
- pattern = Mustermann.new('/:name', type: :express)
126
-
127
- pattern.respond_to? :expand # => true
128
- pattern.expand(name: 'foo') # => '/foo'
129
-
130
- pattern.respond_to? :to_templates # => true
131
- pattern.to_templates # => ['/{name}']
132
- ```
133
-
134
- ## Syntax
135
-
136
- <table>
137
- <thead>
138
- <tr>
139
- <th>Syntax Element</th>
140
- <th>Description</th>
141
- </tr>
142
- </thead>
143
- <tbody>
144
- <tr>
145
- <td><b>:</b><i>name</i></td>
146
- <td>
147
- Captures anything but a forward slash in a semi-greedy fashion. Capture is named <i>name</i>.
148
- Capture behavior can be modified with <tt>capture</tt> and <tt>greedy</tt> option.
149
- </td>
150
- </tr>
151
- <tr>
152
- <td><b>:</b><i>name</i><b>+</b></td>
153
- <td>
154
- Captures one or more segments (with segments being separated by forward slashes).
155
- Capture is named <i>name</i>.
156
- Capture behavior can be modified with <tt>capture</tt> option.
157
- </td>
158
- </tr>
159
- <tr>
160
- <td><b>:</b><i>name</i><b>*</b></td>
161
- <td>
162
- Captures zero or more segments (with segments being separated by forward slashes).
163
- Capture is named <i>name</i>.
164
- Capture behavior can be modified with <tt>capture</tt> option.
165
- </td>
166
- </tr>
167
- <tr>
168
- <td><b>:</b><i>name</i><b>?</b></td>
169
- <td>
170
- Captures anything but a forward slash in a semi-greedy fashion. Capture is named <i>name</i>.
171
- Also matches an empty string.
172
- Capture behavior can be modified with <tt>capture</tt> and <tt>greedy</tt> option.
173
- </td>
174
- </tr>
175
- <tr>
176
- <td><b>:</b><i>name</i><b>(</b><i>regexp</i><b>)</b></td>
177
- <td>
178
- Captures anything matching the <i>regexp</i> regular expression. Capture is named <i>name</i>.
179
- Capture behavior can be modified with <tt>capture</tt>.
180
- </td>
181
- </tr>
182
- <tr>
183
- <td><b>(</b><i>regexp</i><b>)</b></td>
184
- <td>
185
- Captures anything matching the <i>regexp</i> regular expression. Capture is named splat.
186
- Capture behavior can be modified with <tt>capture</tt>.
187
- </td>
188
- </tr>
189
- <tr>
190
- <td><b>/</b></td>
191
- <td>
192
- Matches forward slash. Does not match URI encoded version of forward slash.
193
- </td>
194
- </tr>
195
- <tr>
196
- <td><i>any other character</i></td>
197
- <td>Matches exactly that character or a URI encoded version of it.</td>
198
- </tr>
199
- </tbody>
200
- </table>
36
+ See [docs/patterns/express.md](../docs/patterns/express.md).
201
37
 
202
38
  <a name="-mustermann-fileutils"></a>
203
39
  # FileUtils for Mustermann
@@ -258,573 +94,72 @@ Mustermann::FileUtils.cp_r(':base.:ext' => ':base.bak.:ext')
258
94
  Mustermann::FileUtils.ln_s('lib/:name.rb' => 'bin/:name')
259
95
  ```
260
96
 
261
- <a name="-mustermann-flask"></a>
262
- # Flask Syntax for Mustermann
263
-
264
- This gem implements the `flask` pattern type for Mustermann. It is compatible with [Flask](http://flask.pocoo.org/) and [Werkzeug](http://werkzeug.pocoo.org/).
97
+ <a name="-mustermann-mapper"></a>
98
+ # Mapper for Mustermann
265
99
 
266
100
  ## Overview
267
101
 
268
- **Supported options:**
269
- `capture`, `except`, `greedy`, `space_matches_plus`, `uri_decode`, `converters` and `ignore_unknown_options`
270
-
271
- **External documentation:**
272
- [Werkzeug: URL Routing](http://werkzeug.pocoo.org/docs/0.9/routing/)
102
+ `Mustermann::Mapper` transforms strings according to a set of pattern mappings. Each mapping pairs an input pattern (used to extract parameters) with one or more output patterns (used to expand the result). All mappings that match are applied in insertion order.
273
103
 
274
104
  ``` ruby
275
- require 'mustermann/flask'
276
-
277
- Mustermann.new('/<prefix>/<path:page>', type: :flask).params('/a/b/c') # => { prefix: 'a', page: 'b/c' }
278
-
279
- pattern = Mustermann.new('/<name>', type: :flask)
280
-
281
- pattern.respond_to? :expand # => true
282
- pattern.expand(name: 'foo') # => '/foo'
283
-
284
- pattern.respond_to? :to_templates # => true
285
- pattern.to_templates # => ['/{name}']
286
- ```
287
-
288
- ## Syntax
289
-
290
- <table>
291
- <thead>
292
- <tr>
293
- <th>Syntax Element</th>
294
- <th>Description</th>
295
- </tr>
296
- </thead>
297
- <tbody>
298
- <tr>
299
- <td><b>&lt;</b><i>name</i><b>&gt;</b></td>
300
- <td>
301
- Captures anything but a forward slash in a semi-greedy fashion. Capture is named <i>name</i>.
302
- Capture behavior can be modified with <tt>capture</tt> and <tt>greedy</tt> option.
303
- </td>
304
- </tr>
305
- <tr>
306
- <td><b>&lt;</b><i>converter</i><b>:</b><i>name</i><b>&gt;</b></td>
307
- <td>
308
- Captures depending on the converter constraint. Capture is named <i>name</i>.
309
- Capture behavior can be modified with <tt>capture</tt> and <tt>greedy</tt> option.
310
- See below.
311
- </td>
312
- </tr>
313
- <tr>
314
- <td><b>&lt;</b><i>converter</i><b>(</b><i>arguments</i><b>):</b><i>name</i><b>&gt;</b></td>
315
- <td>
316
- Captures depending on the converter constraint. Capture is named <i>name</i>.
317
- Capture behavior can be modified with <tt>capture</tt> and <tt>greedy</tt> option.
318
- Arguments are separated by comma. An argument can be a simple string, a string enclosed
319
- in single or double quotes, or a key value pair (keys and values being separated by an
320
- equal sign). See below.
321
- </td>
322
- </tr>
323
- <tr>
324
- <td><b>/</b></td>
325
- <td>
326
- Matches forward slash. Does not match URI encoded version of forward slash.
327
- </td>
328
- </tr>
329
- <tr>
330
- <td><i>any other character</i></td>
331
- <td>Matches exactly that character or a URI encoded version of it.</td>
332
- </tr>
333
- </tbody>
334
- </table>
335
-
336
- ## Converters
337
-
338
- ### Builtin Converters
339
-
340
- #### `string`
341
-
342
- Possible arguments: `minlength`, `maxlength`, `length`
343
-
344
- Captures anything but a forward slash in a semi-greedy fashion.
345
- Capture behavior can be modified with <tt>capture</tt> and <tt>greedy</tt> option.
346
-
347
- This is also the default converter.
348
-
349
- Examples:
105
+ require 'mustermann/mapper'
350
106
 
107
+ mapper = Mustermann::Mapper.new("/:page(.:format)?" => ["/:page/view.:format", "/:page/view.html"])
108
+ mapper['/foo'] # => "/foo/view.html"
109
+ mapper['/foo.xml'] # => "/foo/view.xml"
110
+ mapper['/foo/bar'] # => "/foo/bar"
351
111
  ```
352
- <name>
353
- <string:name>
354
- <string(minlength=3,maxlength=10):slug>
355
- <string(length=10):slug>
356
- ```
357
-
358
- #### `int`
359
-
360
- Possible arguments: `min`, `max`, `fixed_digits`
361
112
 
362
- Captures digits.
363
- Captured value will be converted to an Integer.
364
-
365
- Examples:
366
-
367
- ```
368
- <int:id>
369
- <int(min=1,max=5):page>
370
- <int(fixed_digits=16):uuid>
371
- ```
372
-
373
- #### `float`
374
-
375
- Possible arguments: `min`, `max`
376
-
377
- Captures digits with a dot.
378
- Captured value will be converted to an Float.
379
-
380
- Examples:
381
-
382
- ```
383
- <float:precision>
384
- <float(min=0,max=1):precision>
385
- ```
386
-
387
- #### `path`
388
-
389
- Captures anything in a non-greedy fashion.
390
-
391
- Example:
392
-
393
- ```
394
- <path:rest>
395
- ```
396
-
397
- #### `any`
398
-
399
- Possible arguments: List of accepted strings.
400
-
401
- Captures anything that matches one of the arguments exactly.
402
-
403
- Example:
404
-
405
- ```
406
- <any(home,search,contact):page>
407
- ```
408
-
409
- ### Custom Converters
410
-
411
- [Flask patterns](#-pattern-details-flask) support registering custom converters.
412
-
413
- A converter object may implement any of the following methods:
414
-
415
- * `convert`: Should return a block converting a string value to whatever value should end up in the `params` hash.
416
- * `constraint`: Should return a regular expression limiting which input string will match the capture.
417
- * `new`: Returns an object that may respond to `convert` and/or `constraint` as described above. Any arguments used for the converter inside the pattern will be passed to `new`.
113
+ You can also pass additional values at conversion time to supplement or override captured parameters:
418
114
 
419
115
  ``` ruby
420
- require 'mustermann/flask'
421
-
422
- SimpleConverter = Struct.new(:constraint, :convert)
423
- id_converter = SimpleConverter.new(/\d/, -> s { s.to_i })
424
-
425
- class NumConverter
426
- def initialize(base: 10)
427
- @base = Integer(base)
428
- end
429
-
430
- def convert
431
- -> s { s.to_i(@base) }
432
- end
433
-
434
- def constraint
435
- @base > 10 ? /[\da-#{(@base-1).to_s(@base)}]/ : /[0-#{@base-1}]/
436
- end
437
- end
438
-
439
- pattern = Mustermann.new('/<id:id>/<num(base=8):oct>/<num(base=16):hex>',
440
- type: :flask, converters: { id: id_converter, num: NumConverter})
441
-
442
- pattern.params('/10/12/f1') # => {"id"=>10, "oct"=>10, "hex"=>241}
116
+ mapper = Mustermann::Mapper.new("/:example" => "(/:prefix)?/:example.html")
117
+ mapper['/foo', prefix: 'en'] # => "/en/foo.html"
443
118
  ```
444
119
 
445
- ### Global Converters
120
+ ## Building a Mapper
446
121
 
447
- It is also possible to register a converter for all flask patterns, using `register_converter`:
122
+ Mappings can be supplied as a hash, added via `[]=`, or built with a block:
448
123
 
449
124
  ``` ruby
450
- Mustermann::Flask.register_converter(:id, id_converter)
451
- Mustermann::Flask.register_converter(:num, NumConverter)
125
+ # Hash argument
126
+ mapper = Mustermann::Mapper.new("/:a" => "/:a.html", "/:a/:b" => "/:b/:a")
452
127
 
453
- pattern = Mustermann.new('/<id:id>/<num(base=8):oct>/<num(base=16):hex>', type: :flask)
454
- pattern.params('/10/12/f1') # => {"id"=>10, "oct"=>10, "hex"=>241}
455
- ```
456
-
457
- There is a handy syntax for quickly creating new converter classes: When you pass a block instead of a converter object, it will yield a generic converter with setters and getters for `convert` and `constraint`, and any arguments passed to the converter.
128
+ # Block (zero-argument, returns a hash)
129
+ mapper = Mustermann::Mapper.new { { "/:a" => "/:a.html" } }
458
130
 
459
- ``` ruby
460
- require 'mustermann/flask'
461
-
462
- Mustermann::Flask.register_converter(:id) do |converter|
463
- converter.constraint = /\d/
464
- converter.convert = -> s { s.to_i }
131
+ # Block (one-argument, imperative)
132
+ mapper = Mustermann::Mapper.new do |m|
133
+ m["/:a"] = "/:a.html"
465
134
  end
466
135
 
467
- Mustermann::Flask.register_converter(:num) do |converter, base: 10|
468
- converter.constraint = base > 10 ? /[\da-#{(@base-1).to_s(base)}]/ : /[0-#{base-1}]/
469
- converter.convert = -> s { s.to_i(base) }
470
- end
471
-
472
- pattern = Mustermann.new('/<id:id>/<num(base=8):oct>/<num(base=16):hex>', type: :flask)
473
- pattern.params('/10/12/f1') # => {"id"=>10, "oct"=>10, "hex"=>241}
136
+ # Incremental
137
+ mapper = Mustermann::Mapper.new
138
+ mapper["/:a"] = "/:a.html"
474
139
  ```
475
140
 
476
- ### Subclassing
477
-
478
- Registering global converters will make these available for all Flask patterns. It might even override already registered converters. This global state might break unrelated code.
479
-
480
- It is therefore recommended that, if you don't want to pass in the converters option for every pattern, you create your own subclass of `Mustermann::Flask`.
481
-
482
- ``` ruby
483
- require 'mustermann/flask'
484
-
485
- MyFlask = Class.new(Mustermann::Flask)
141
+ The output value may be a String, a `Mustermann::Pattern`, an `Array` of either (tried in order until one expands successfully), or a `Mustermann::Expander` directly.
486
142
 
487
- MyFlask.register_converter(:id) do |converter|
488
- converter.constraint = /\d/
489
- converter.convert = -> s { s.to_i }
490
- end
491
-
492
- MyFlask.register_converter(:num) do |converter, base: 10|
493
- converter.constraint = base > 10 ? /[\da-#{(@base-1).to_s(base)}]/ : /[0-#{base-1}]/
494
- converter.convert = -> s { s.to_i(base) }
495
- end
496
-
497
- pattern = MyFlask.new('/<id:id>/<num(base=8):oct>/<num(base=16):hex>')
498
- pattern.params('/10/12/f1') # => {"id"=>10, "oct"=>10, "hex"=>241}
499
- ```
500
-
501
- You can even register this type for usage with `Mustermann.new`:
143
+ <a name="-mustermann-flask"></a>
144
+ # Flask Syntax for Mustermann
502
145
 
503
- ``` ruby
504
- Mustermann.register(:my_flask, MyFlask)
505
- pattern = Mustermann.new('/<id:id>/<num(base=8):oct>/<num(base=16):hex>', type: :my_flask)
506
- pattern.params('/10/12/f1') # => {"id"=>10, "oct"=>10, "hex"=>241}
507
- ```
146
+ See [docs/patterns/flask.md](../docs/patterns/flask.md).
508
147
 
509
148
  <a name="-mustermann-pyramid"></a>
510
149
  # Pyramid Syntax for Mustermann
511
150
 
512
- This gem implements the `pyramid` pattern type for Mustermann. It is compatible with [Pyramid](http://www.pylonsproject.org/projects/pyramid/about) and [Pylons](http://www.pylonsproject.org/projects/pylons-framework/about).
513
-
514
- ## Overview
515
-
516
- **Supported options:**
517
- `capture`, `except`, `greedy`, `space_matches_plus`, `uri_decode` and `ignore_unknown_options`
518
-
519
- **External Documentation:** [Pylons Framework: URL Configuration](http://docs.pylonsproject.org/projects/pylons-webframework/en/latest/configuration.html#url-config), [Pylons Book: Routes in Detail](http://pylonsbook.com/en/1.0/urls-routing-and-dispatch.html#routes-in-detail), [Pyramid: Route Pattern Syntax](http://docs.pylonsproject.org/projects/pyramid/en/1.5-branch/narr/urldispatch.html#route-pattern-syntax)
520
-
521
- ``` ruby
522
- require 'mustermann/pyramid'
523
-
524
- Mustermann.new('/{prefix}/*suffix', type: :pyramid).params('/a/b/c') # => { prefix: 'a', suffix: ['b', 'c'] }
525
-
526
- pattern = Mustermann.new('/{name}', type: :pyramid)
527
-
528
- pattern.respond_to? :expand # => true
529
- pattern.expand(name: 'foo') # => '/foo'
530
-
531
- pattern.respond_to? :to_templates # => true
532
- pattern.to_templates # => ['/{name}']
533
- ```
534
-
535
- ## Syntax
536
-
537
-
538
- <table>
539
- <thead>
540
- <tr>
541
- <th>Syntax Element</th>
542
- <th>Description</th>
543
- </tr>
544
- </thead>
545
- <tbody>
546
- <tr>
547
- <td><b>&#123;</b><i>name</i><b>&#125;</b></td>
548
- <td>
549
- Captures anything but a forward slash in a semi-greedy fashion. Capture is named <i>name</i>.
550
- Capture behavior can be modified with <tt>capture</tt> and <tt>greedy</tt> option.
551
- </td>
552
- </tr>
553
- <tr>
554
- <td><b>&#123;</b><i>name</i><b>:</b><i>regexp</i><b>&#125;</b></td>
555
- <td>
556
- Captures anything matching the <i>regexp</i> regular expression. Capture is named <i>name</i>.
557
- Capture behavior can be modified with <tt>capture</tt>.
558
- </td>
559
- </tr>
560
- <tr>
561
- <td><b>*</b><i>name</i></td>
562
- <td>
563
- Captures anything in a non-greedy fashion. Capture is named <i>name</i>.
564
- </td>
565
- </tr>
566
- <tr>
567
- <td><b>/</b></td>
568
- <td>
569
- Matches forward slash. Does not match URI encoded version of forward slash.
570
- </td>
571
- </tr>
572
- <tr>
573
- <td><i>any other character</i></td>
574
- <td>Matches exactly that character or a URI encoded version of it.</td>
575
- </tr>
576
- </tbody>
577
- </table>
578
-
579
- <a name="-mustermann-rails"></a>
580
- # Rails Syntax for Mustermann
581
-
582
- This gem implements the `rails` pattern type for Mustermann. It is compatible with [Ruby on Rails](http://rubyonrails.org/), [Journey](https://github.com/rails/journey), the [http_router gem](https://github.com/joshbuddy/http_router), [Lotus](http://lotusrb.org/) and [Scalatra](http://scalatra.org/) (if [configured](http://scalatra.org/2.3/guides/http/routes.html#toc_248))</td>
583
-
584
- ## Overview
585
-
586
- **Supported options:**
587
- `capture`, `except`, `greedy`, `space_matches_plus`, `uri_decode`, `version`, and `ignore_unknown_options`.
588
-
589
- **External documentation:**
590
- [Ruby on Rails Guides: Routing](http://guides.rubyonrails.org/routing.html).
591
-
592
- ``` ruby
593
- require 'mustermann'
594
-
595
- pattern = Mustermann.new('/:example', type: :rails)
596
- pattern === "/foo.bar" # => true
597
- pattern === "/foo/bar" # => false
598
- pattern.params("/foo.bar") # => { "example" => "foo.bar" }
599
- pattern.params("/foo/bar") # => nil
600
-
601
- pattern = Mustermann.new('/:example(/:optional)', type: :rails)
602
- pattern === "/foo.bar" # => true
603
- pattern === "/foo/bar" # => true
604
- pattern.params("/foo.bar") # => { "example" => "foo.bar", "optional" => nil }
605
- pattern.params("/foo/bar") # => { "example" => "foo", "optional" => "bar" }
606
-
607
- pattern = Mustermann.new('/*example', type: :rails)
608
- pattern === "/foo.bar" # => true
609
- pattern === "/foo/bar" # => true
610
- pattern.params("/foo.bar") # => { "example" => "foo.bar" }
611
- pattern.params("/foo/bar") # => { "example" => "foo/bar" }
612
- ```
613
-
614
- ## Rails Compatibility
615
-
616
- Rails syntax changed over time. You can target different Ruby on Rails versions by setting the `version` option to the desired Rails version.
617
-
618
- The default is `4.2`. Versions prior to `2.3` are not supported.
619
-
620
- ``` ruby
621
- require 'mustermann'
622
- Mustermann.new('/', type: :rails, version: "2.3")
623
- Mustermann.new('/', type: :rails, version: "3.0.0")
624
-
625
- require 'rails'
626
- Mustermann.new('/', type: :rails, version: Rails::VERSION::STRING)
627
- ```
628
-
629
- ## Syntax
630
-
631
- <table>
632
- <thead>
633
- <tr>
634
- <th>Syntax Element</th>
635
- <th>Description</th>
636
- </tr>
637
- </thead>
638
- <tbody>
639
- <tr>
640
- <td><b>:</b><i>name</i></td>
641
- <td>
642
- Captures anything but a forward slash in a semi-greedy fashion. Capture is named <i>name</i>.
643
- Capture behavior can be modified with tt>capture</tt> and <tt>greedy</tt> option.
644
- </td>
645
- </tr>
646
- <tr>
647
- <td><b>*</b><i>name</i></td>
648
- <td>
649
- Captures anything in a non-greedy fashion. Capture is named <i>name</i>.
650
- </td>
651
- </tr>
652
- <tr>
653
- <td><b>(</b><i>expression</i><b>)</b></td>
654
- <td>Enclosed <i>expression</i> is optional. Not available in 2.3 compatibility mode.</td>
655
- </tr>
656
- <tr>
657
- <td><b>/</b></td>
658
- <td>
659
- Matches forward slash. Does not match URI encoded version of forward slash.
660
- </td>
661
- </tr>
662
- <tr>
663
- <td><b>\</b><i>x</i></td>
664
- <td>
665
- In 3.x compatibility mode and starting with 4.2:
666
- Matches <i>x</i> or URI encoded version of <i>x</i>. For instance <tt>\*</tt> matches <tt>*</tt>.<br>
667
- In 4.0 or 4.1 compatibility mode:
668
- <b>\</b> is ignored, <i>x</i> is parsed normally.<br>
669
- </td>
670
- </tr>
671
- <tr>
672
- <td><i>expression</i> <b>|</b> <i>expression</i></td>
673
- <td>
674
- 3.2+ mode: This will raise a `Mustermann::ParseError`. While Ruby on Rails happily parses this character, it will result in broken routes due to a buggy implementation.<br>
675
- 5.0 mode: It will match if any of the nested expressions matches.
676
- </td>
677
- </tr>
678
- <tr>
679
- <td><i>any other character</i></td>
680
- <td>Matches exactly that character or a URI encoded version of it.</td>
681
- </tr>
682
- </tbody>
683
- </table>
151
+ See [docs/patterns/pyramid.md](../docs/patterns/pyramid.md).
684
152
 
685
153
  <a name="-mustermann-shell"></a>
686
154
  # Shell Syntax for Mustermann
687
155
 
688
- This gem implements the `shell` pattern type for Mustermann. It is compatible with common Unix shells (like bash or zsh).
689
-
690
- ## Overview
691
-
692
- **Supported options:** `uri_decode` and `ignore_unknown_options`.
693
-
694
- **External documentation:** [Ruby's fnmatch](http://www.ruby-doc.org/core-2.1.4/File.html#method-c-fnmatch), [Wikipedia: Glob (programming)](http://en.wikipedia.org/wiki/Glob_(programming))
695
-
696
- ``` ruby
697
- require 'mustermann'
698
-
699
- pattern = Mustermann.new('/*', type: :shell)
700
- pattern === "/foo.bar" # => true
701
- pattern === "/foo/bar" # => false
702
-
703
- pattern = Mustermann.new('/**/*', type: :shell)
704
- pattern === "/foo.bar" # => true
705
- pattern === "/foo/bar" # => true
706
-
707
- pattern = Mustermann.new('/{foo,bar}', type: :shell)
708
- pattern === "/foo" # => true
709
- pattern === "/bar" # => true
710
- pattern === "/baz" # => false
711
- ```
712
-
713
- ## Syntax
714
-
715
- <table>
716
- <thead>
717
- <tr>
718
- <th>Syntax Element</th>
719
- <th>Description</th>
720
- </tr>
721
- </thead>
722
- <tbody>
723
- <tr>
724
- <td><b>*</b></td>
725
- <td>Matches anything but a slash.</td>
726
- </tr>
727
- <tr>
728
- <td><b>**</b></td>
729
- <td>Matches anything.</td>
730
- </tr>
731
- <tr>
732
- <td><b>[</b><i>set</i><b>]</b></td>
733
- <td>Matches one character in <i>set</i>.</td>
734
- </tr>
735
- <tr>
736
- <td><b>&#123;</b><i>a</i>,<i>b</i><b>&#125;</b></td>
737
- <td>Matches <i>a</i> or <i>b</i>.</td>
738
- </tr>
739
- <tr>
740
- <td><b>\</b><i>x</i></td>
741
- <td>Matches <i>x</i> or URI encoded version of <i>x</i>. For instance <tt>\*</tt> matches <tt>*</tt>.</td>
742
- </tr>
743
- <tr>
744
- <td><i>any other character</i></td>
745
- <td>Matches exactly that character or a URI encoded version of it.</td>
746
- </tr>
747
- </tbody>
748
- </table>
156
+ See [docs/patterns/shell.md](../docs/patterns/shell.md).
749
157
 
750
158
 
751
159
  <a name="-mustermann-simple"></a>
752
160
  # Simple Syntax for Mustermann
753
161
 
754
- This gem implements the `simple` pattern type for Mustermann. It is compatible with [Sinatra](http://www.sinatrarb.com/) (1.x), [Scalatra](http://scalatra.org/) and [Dancer](http://perldancer.org/).
755
-
756
- ## Overview
757
-
758
- **Supported options:**
759
- `greedy`, `space_matches_plus`, `uri_decode` and `ignore_unknown_options`.
760
-
761
- This is useful for porting an application that relies on this behavior to a later Sinatra version and to make sure Sinatra 2.0 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.
762
-
763
- ``` ruby
764
- require 'mustermann'
765
-
766
- pattern = Mustermann.new('/:example', type: :simple)
767
- pattern === "/foo.bar" # => true
768
- pattern === "/foo/bar" # => false
769
- pattern.params("/foo.bar") # => { "example" => "foo.bar" }
770
- pattern.params("/foo/bar") # => nil
771
-
772
- pattern = Mustermann.new('/:example/?:optional?', type: :simple)
773
- pattern === "/foo.bar" # => true
774
- pattern === "/foo/bar" # => true
775
- pattern.params("/foo.bar") # => { "example" => "foo.bar", "optional" => nil }
776
- pattern.params("/foo/bar") # => { "example" => "foo", "optional" => "bar" }
777
-
778
- pattern = Mustermann.new('/*', type: :simple)
779
- pattern === "/foo.bar" # => true
780
- pattern === "/foo/bar" # => true
781
- pattern.params("/foo.bar") # => { "splat" => ["foo.bar"] }
782
- pattern.params("/foo/bar") # => { "splat" => ["foo/bar"] }
783
- ```
784
-
785
- ## Syntax
786
-
787
- <table>
788
- <thead>
789
- <tr>
790
- <th>Syntax Element</th>
791
- <th>Description</th>
792
- </tr>
793
- </thead>
794
- <tbody>
795
- <tr>
796
- <td><b>:</b><i>name</i></td>
797
- <td>
798
- Captures anything but a forward slash in a greedy fashion. Capture is named <i>name</i>.
799
- </td>
800
- </tr>
801
- <tr>
802
- <td><b>*</b></td>
803
- <td>
804
- Captures anything in a non-greedy fashion. Capture is named splat.
805
- It is always an array of captures, as you can use <tt>*</tt> more than once in a pattern.
806
- </td>
807
- </tr>
808
- <tr>
809
- <td><i>x</i><b>?</b></td>
810
- <td>Makes <i>x</i> optional. For instance <tt>foo?</tt> matches <tt>foo</tt> or <tt>fo</tt>.</td>
811
- </tr>
812
- <tr>
813
- <td><b>/</b></td>
814
- <td>
815
- Matches forward slash. Does not match URI encoded version of forward slash.
816
- </td>
817
- </tr>
818
- <tr>
819
- <td><i>any special character</i></td>
820
- <td>Matches exactly that character or a URI encoded version of it.</td>
821
- </tr>
822
- <tr>
823
- <td><i>any other character</i></td>
824
- <td>Matches exactly that character.</td>
825
- </tr>
826
- </tbody>
827
- </table>
162
+ See [docs/patterns/simple.md](../docs/patterns/simple.md).
828
163
 
829
164
  <a name="-mustermann-strscan"></a>
830
165
  # String Scanner for Mustermann
@@ -866,91 +201,47 @@ You can also pass in default options for ad hoc patterns when creating the scann
866
201
  scanner = Mustermann::StringScanner.new(input, type: :shell)
867
202
  ```
868
203
 
869
- <a name="-mustermann-uri-template"></a>
870
- # URI Template Syntax for Mustermann
871
-
872
- This gem implements the `uri-template` (or `template`) pattern type for Mustermann. It is compatible with [RFC 6570](https://tools.ietf.org/html/rfc6570) (level 4), [JSON API](http://jsonapi.org/), [JSON Home Documents](http://tools.ietf.org/html/draft-nottingham-json-home-02) and [many more](https://code.google.com/p/uri-templates/wiki/Implementations)
204
+ <a name="-mustermann-to-pattern"></a>
205
+ # `to_pattern` for Mustermann
873
206
 
874
207
  ## Overview
875
208
 
876
- **Supported options:**
877
- `capture`, `except`, `greedy`, `space_matches_plus`, `uri_decode`, and `ignore_unknown_options`.
878
-
879
- Please keep the following in mind:
880
-
881
- > "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."
882
- > &mdash; *RFC 6570, Sec 1.5: "Limitations"*
209
+ `mustermann/to_pattern` adds a `to_pattern` method to `String`, `Symbol`, `Regexp`, `Array`, and `Mustermann::Pattern`, and provides the `Mustermann::ToPattern` mixin so you can add the same method to your own classes.
883
210
 
884
211
  ``` ruby
885
- require 'mustermann'
212
+ require 'mustermann/to_pattern'
886
213
 
887
- pattern = Mustermann.new('/{example}', type: :template)
888
- pattern === "/foo.bar" # => true
889
- pattern === "/foo/bar" # => false
890
- pattern.params("/foo.bar") # => { "example" => "foo.bar" }
891
- pattern.params("/foo/bar") # => nil
892
-
893
- pattern = Mustermann.new("{/segments*}/{page}{.ext,cmpr:2}", type: :template)
894
- pattern.params("/a/b/c.tar.gz") # => {"segments"=>["a","b"], "page"=>"c", "ext"=>"tar", "cmpr"=>"gz"}
214
+ "/foo".to_pattern # => #<Mustermann::Sinatra:"/foo">
215
+ "/foo".to_pattern(type: :rails) # => #<Mustermann::Rails:"/foo">
216
+ %r{/foo}.to_pattern # => #<Mustermann::Regular:"\\/foo">
217
+ "/foo".to_pattern.to_pattern # => #<Mustermann::Sinatra:"/foo">
895
218
  ```
896
219
 
897
- ## Generating URI Templates
220
+ ## `Mustermann::ToPattern` mixin
898
221
 
899
- You do not need to use URI templates (and this gem) if all you want is reusing them for hypermedia links. Most other pattern types support generating these (via `#to_pattern`):
222
+ Include `Mustermann::ToPattern` in any class to get a `to_pattern` method driven by its `to_s` output:
900
223
 
901
224
  ``` ruby
902
- require 'mustermann'
903
-
904
- Mustermann.new('/:name').to_templates # => ['/{name}']
905
- ```
225
+ require 'mustermann/to_pattern'
906
226
 
907
- Moreover, Mustermann's default pattern type implements a subset of URI templates (`{capture}` and `{+capture}`) and can therefore also be used for simple templates/
227
+ class MyRoute
228
+ include Mustermann::ToPattern
908
229
 
909
- ``` ruby
910
- require 'mustermann'
230
+ def to_s
231
+ "/users/:id"
232
+ end
233
+ end
911
234
 
912
- Mustermann.new('/{name}').expand(name: "example") # => "/example"
235
+ MyRoute.new.to_pattern # => #<Mustermann::Sinatra:"/users/:id">
236
+ MyRoute.new.to_pattern(type: :rails) # => #<Mustermann::Rails:"/users/:id">
913
237
  ```
914
238
 
915
- ## Syntax
916
-
917
- <table>
918
- <thead>
919
- <tr>
920
- <th>Syntax Element</th>
921
- <th>Description</th>
922
- </tr>
923
- </thead>
924
- <tbody>
925
- <tr>
926
- <td><b>&#123;</b><i>o</i> <i>var</i> <i>m</i><b>,</b> <i>var</i> <i>m</i><b>,</b> ...<b>&#125;</b></td>
927
- <td>
928
- Captures expansion.
929
- Operator <i>o</i>: <code>+ # . / ; ? &amp;</tt> or none.
930
- Modifier <i>m</i>: <code>:num *</tt> or none.
931
- </td>
932
- </tr>
933
- <tr>
934
- <td><b>/</b></td>
935
- <td>
936
- Matches forward slash. Does not match URI encoded version of forward slash.
937
- </td>
938
- </tr>
939
- <tr>
940
- <td><i>any other character</i></td>
941
- <td>Matches exactly that character or a URI encoded version of it.</td>
942
- </tr>
943
- </tbody>
944
- </table>
945
-
946
- The operators `+` and `#` will always match non-greedy, whereas all other operators match semi-greedy by default.
947
- All modifiers and operators are supported. However, it does not parse lists as single values without the *explode* modifier (aka *star*).
948
- Parametric operators (`;`, `?` and `&`) currently only match parameters in given order.
949
-
950
- Note that it differs from URI templates in that it takes the unescaped version of special character instead of the escaped version.
951
-
952
- If you reuse the exact same templates and expose them via an external API meant for expansion,
953
- you should set `uri_decode` to `false` in order to conform with the specification.
239
+ If your class wraps another object (via `__getobj__`, as in `Delegator` subclasses), `to_pattern` will unwrap it before converting.
240
+
241
+ <a name="-mustermann-uri-template"></a>
242
+ # URI Template Syntax for Mustermann
243
+
244
+ See [docs/patterns/template.md](../docs/patterns/template.md).
954
245
 
955
246
 
956
247
  <a name="-mustermann-visualizer"></a>
@@ -1127,15 +418,6 @@ The **s-expression like syntax** looks as follows:
1127
418
  * Full strings are Ruby strings enclosed by double quotes.
1128
419
  * Spaces before or after parens are optional.
1129
420
 
1130
- ### IRB/Pry integration
1131
-
1132
- When `mustermann` is being loaded from within an IRB or Pry session, it will automatically load `mustermann/visualizer` too, if possible.
1133
- When displayed as result, it will be highlighted.
1134
-
1135
- ![](irb.png)
1136
-
1137
- In Pry, this will even work when nested inside other objects (like as element on an array).
1138
-
1139
421
  ## Tree Rendering
1140
422
 
1141
423
  ![](tree.png)
@@ -1152,4 +434,3 @@ For patterns not based on an AST (shell, simple, regexp), it will print out a si
1152
434
  pattern (not AST based) "/example"
1153
435
 
1154
436
  It will display a tree for identity patterns. While these are not based on an AST internally, Mustermann supports generating an AST for these patterns.
1155
-
@@ -106,7 +106,7 @@ module Mustermann
106
106
 
107
107
  # Allows you to register your own converters.
108
108
  #
109
- # It is reommended to use this on a subclass, so to not influence other subsystems
109
+ # It is recommended to use this on a subclass, so to not influence other subsystems
110
110
  # using flask templates.
111
111
  #
112
112
  # The object passed in as converter can implement #convert and/or #constraint.
@@ -135,7 +135,7 @@ module Mustermann
135
135
  # MyPattern.new("/<up:name>").params('/foo') # => { "name" => "FOO" }
136
136
  #
137
137
  # @example with converter class
138
- # require 'mustermann/flasl'
138
+ # require 'mustermann/flask'
139
139
  #
140
140
  # class MyPattern < Mustermann::Flask
141
141
  # class Converter
@@ -0,0 +1,88 @@
1
+ # frozen_string_literal: true
2
+ require 'mustermann'
3
+ require 'mustermann/expander'
4
+ require 'mustermann/set'
5
+
6
+ module Mustermann
7
+ # A mapper allows mapping one string to another based on pattern parsing and expanding.
8
+ #
9
+ # @example
10
+ # require 'mustermann/mapper'
11
+ # mapper = Mustermann::Mapper.new("/:foo" => "/:foo.html")
12
+ # mapper['/example'] # => "/example.html"
13
+ class Mapper
14
+ # Creates a new mapper.
15
+ #
16
+ # @overload initialize(**options)
17
+ # @param options [Hash] options The options hash
18
+ # @yield block for generating mappings as a hash
19
+ # @yieldreturn [Hash] see {#update}
20
+ #
21
+ # @example
22
+ # require 'mustermann/mapper'
23
+ # Mustermann::Mapper.new(type: :rails) {{
24
+ # "/:foo" => ["/:foo.html", "/:foo.:format"]
25
+ # }}
26
+ #
27
+ # @overload initialize(**options)
28
+ # @param options [Hash] options The options hash
29
+ # @yield block for generating mappings as a hash
30
+ # @yieldparam mapper [Mustermann::Mapper] the mapper instance
31
+ #
32
+ # @example
33
+ # require 'mustermann/mapper'
34
+ # Mustermann::Mapper.new(type: :rails) do |mapper|
35
+ # mapper["/:foo"] = ["/:foo.html", "/:foo.:format"]
36
+ # end
37
+ #
38
+ # @overload initialize(map = {}, **options)
39
+ # @param map [Hash] see {#update}
40
+ # @param [Hash] options The options hash
41
+ #
42
+ # @example map before options
43
+ # require 'mustermann/mapper'
44
+ # Mustermann::Mapper.new({"/:foo" => "/:foo.html"}, type: :rails)
45
+ def initialize(map = {}, additional_values: :ignore, **options, &block)
46
+ @options = options
47
+ @additional_values = additional_values
48
+ @set = Set.new(use_trie: false, use_cache: false, **options)
49
+ block.arity == 0 ? update(yield) : yield(self) if block
50
+ update(map) if map
51
+ end
52
+
53
+ # Add multiple mappings.
54
+ #
55
+ # @param map [Hash{String, Pattern: String, Pattern, Arry<String, Pattern>, Expander}] the mapping
56
+ def update(map)
57
+ map.to_h.each_pair do |input, output|
58
+ output = Expander.new(*output, additional_values: @additional_values, **@options) unless output.is_a? Expander
59
+ @set.add(input, output)
60
+ end
61
+ end
62
+
63
+ # @return [Hash{Patttern: Expander}] Hash version of the mapper.
64
+ def to_h = @set.patterns.to_h { [_1, @set[_1]] }
65
+
66
+ # Convert a string according to mappings. You can pass in additional params.
67
+ #
68
+ # @example mapping with and without additional parameters
69
+ # mapper = Mustermann::Mapper.new("/:example" => "(/:prefix)?/:example.html")
70
+ #
71
+ def convert(input, values = {})
72
+ @set.match_all(input).inject(input) do |current, m|
73
+ params = Hash[values.merge(m.params).map { |k, v| [k.to_s, v] }]
74
+ m.value.expandable?(params) ? m.value.expand(params) : current
75
+ end
76
+ end
77
+
78
+ # Add a single mapping.
79
+ #
80
+ # @param key [String, Pattern] format of the input string
81
+ # @param value [String, Pattern, Arry<String, Pattern>, Expander] format of the output string
82
+ def []=(key, value)
83
+ update key => value
84
+ end
85
+
86
+ alias_method :[], :convert
87
+ end
88
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+ require 'set'
3
+ require 'thread'
4
+ require 'mustermann'
5
+
6
+ module Mustermann
7
+ # A simple, persistent cache for creating repositories.
8
+ #
9
+ # @example
10
+ # require 'mustermann/pattern_cache'
11
+ # cache = Mustermann::PatternCache.new
12
+ #
13
+ # # use this instead of Mustermann.new
14
+ # pattern = cache.create_pattern("/:name", type: :rails)
15
+ #
16
+ # @note
17
+ # {Mustermann::Pattern.new} (which is used by {Mustermann.new}) will reuse instances that have
18
+ # not yet been garbage collected. You only need an extra cache if you do not keep a reference to
19
+ # the patterns around.
20
+ #
21
+ # @api private
22
+ class PatternCache
23
+ # @param [Hash] pattern_options default options used for {#create_pattern}
24
+ def initialize(**pattern_options)
25
+ @cached = ::Set.new
26
+ @mutex = Mutex.new
27
+ @pattern_options = pattern_options
28
+ end
29
+
30
+ # @param (see Mustermann.new)
31
+ # @return (see Mustermann.new)
32
+ # @raise (see Mustermann.new)
33
+ # @see Mustermann.new
34
+ def create_pattern(string, **pattern_options)
35
+ pattern = Mustermann.new(string, **pattern_options, **@pattern_options)
36
+ @mutex.synchronize { @cached.add(pattern) } unless @cached.include? pattern
37
+ pattern
38
+ end
39
+
40
+ # Removes all pattern instances from the cache.
41
+ def clear
42
+ @mutex.synchronize { @cached.clear }
43
+ end
44
+
45
+ # @return [Integer] number of currently cached patterns
46
+ def size
47
+ @mutex.synchronize { @cached.size }
48
+ end
49
+ end
50
+ end
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
  require 'mustermann'
3
3
  require 'mustermann/pattern'
4
- require 'mustermann/simple_match'
5
4
 
6
5
  module Mustermann
7
6
  # Matches strings that are identical to the pattern.
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+ require 'mustermann'
3
+
4
+ module Mustermann
5
+ # Mixin for adding {#to_pattern} ducktyping to objects.
6
+ #
7
+ # @example
8
+ # require 'mustermann/to_pattern'
9
+ #
10
+ # class Foo
11
+ # include Mustermann::ToPattern
12
+ #
13
+ # def to_s
14
+ # ":foo/:bar"
15
+ # end
16
+ # end
17
+ #
18
+ # Foo.new.to_pattern # => #<Mustermann::Sinatra:":foo/:bar">
19
+ #
20
+ # By default included into String, Symbol, Regexp, Array and {Mustermann::Pattern}.
21
+ module ToPattern
22
+ PRIMITIVES = [String, Symbol, Array, Regexp, Mustermann::Pattern]
23
+ private_constant :PRIMITIVES
24
+
25
+ # Converts the object into a {Mustermann::Pattern}.
26
+ #
27
+ # @example converting a string
28
+ # ":name.png".to_pattern # => #<Mustermann::Sinatra:":name.png">
29
+ #
30
+ # @example converting a string with options
31
+ # "/*path".to_pattern(type: :rails) # => #<Mustermann::Rails:"/*path">
32
+ #
33
+ # @example converting a regexp
34
+ # /.*/.to_pattern # => #<Mustermann::Regular:".*">
35
+ #
36
+ # @example converting a pattern
37
+ # Mustermann.new("foo").to_pattern # => #<Mustermann::Sinatra:"foo">
38
+ #
39
+ # @param [Hash] options The options hash.
40
+ # @return [Mustermann::Pattern] pattern corresponding to object.
41
+ def to_pattern(**options)
42
+ input = self if PRIMITIVES.any? { |p| self.is_a? p }
43
+ input ||= __getobj__ if respond_to?(:__getobj__)
44
+ Mustermann.new(input || to_s, **options)
45
+ end
46
+
47
+ PRIMITIVES.each do |klass|
48
+ append_features(klass)
49
+ end
50
+ end
51
+ end
@@ -44,26 +44,12 @@ module Mustermann
44
44
  caller_locations.first.label == 'puts' ? to_ansi : super
45
45
  end
46
46
 
47
- # If invoked directly by IRB, same as {#color_inspect}, otherwise same as {Mustermann::Pattern#inspect}.
48
- def inspect
49
- caller_locations.first.base_label == '<module:IRB>' ? color_inspect : super
50
- end
51
-
52
47
  # @return [String] ANSI colorized version of {Mustermann::Pattern#inspect}
53
48
  def color_inspect(base_color = nil, **theme)
54
49
  base_color ||= Highlight::DEFAULT_THEME[:base01]
55
50
  template = is_a?(Composite) ? "*#<%p:(*%s*)>*" : "*#<%p:*%s*>*"
56
51
  Hansi.render(template, self.class, to_ansi(inspect: true, **theme), {"*" => base_color})
57
52
  end
58
-
59
- # If invoked directly by IRB, same as {#color_inspect}, otherwise same as Object#pretty_print.
60
- def pretty_print(q)
61
- if q.class.name.to_s[/[^:]+$/] == "ColorPrinter"
62
- q.text(color_inspect, inspect.length)
63
- else
64
- super
65
- end
66
- end
67
53
  end
68
54
  end
69
55
  end
metadata CHANGED
@@ -1,10 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mustermann-contrib
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.0
4
+ version: 4.0.0.alpha
5
5
  platform: ruby
6
6
  authors:
7
7
  - Konstantin Haase
8
+ - Kunpei Sakai
9
+ - Patrik Ragnarsson
10
+ - Jordan Owens
8
11
  - Zachary Scott
9
12
  bindir: bin
10
13
  cert_chain: []
@@ -16,14 +19,14 @@ dependencies:
16
19
  requirements:
17
20
  - - '='
18
21
  - !ruby/object:Gem::Version
19
- version: 3.1.0
22
+ version: 4.0.0.alpha
20
23
  type: :runtime
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
24
27
  - - '='
25
28
  - !ruby/object:Gem::Version
26
- version: 3.1.0
29
+ version: 4.0.0.alpha
27
30
  - !ruby/object:Gem::Dependency
28
31
  name: hansi
29
32
  requirement: !ruby/object:Gem::Requirement
@@ -52,12 +55,15 @@ files:
52
55
  - lib/mustermann/file_utils/glob_pattern.rb
53
56
  - lib/mustermann/fileutils.rb
54
57
  - lib/mustermann/flask.rb
58
+ - lib/mustermann/mapper.rb
59
+ - lib/mustermann/pattern_cache.rb
55
60
  - lib/mustermann/pyramid.rb
56
61
  - lib/mustermann/shell.rb
57
62
  - lib/mustermann/simple.rb
58
63
  - lib/mustermann/string_scanner.rb
59
64
  - lib/mustermann/strscan.rb
60
65
  - lib/mustermann/template.rb
66
+ - lib/mustermann/to_pattern.rb
61
67
  - lib/mustermann/uri_template.rb
62
68
  - lib/mustermann/visualizer.rb
63
69
  - lib/mustermann/visualizer/highlight.rb
@@ -78,7 +84,11 @@ files:
78
84
  homepage: https://github.com/sinatra/mustermann
79
85
  licenses:
80
86
  - MIT
81
- metadata: {}
87
+ metadata:
88
+ bug_tracker_uri: https://github.com/sinatra/mustermann/issues
89
+ changelog_uri: https://github.com/sinatra/mustermann/blob/main/CHANGELOG.md
90
+ documentation_uri: https://github.com/sinatra/mustermann/tree/main/mustermann-contrib#readme
91
+ source_code_uri: https://github.com/sinatra/mustermann/tree/main/mustermann-contrib
82
92
  rdoc_options: []
83
93
  require_paths:
84
94
  - lib
@@ -86,7 +96,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
86
96
  requirements:
87
97
  - - ">="
88
98
  - !ruby/object:Gem::Version
89
- version: 2.7.0
99
+ version: 3.3.0
90
100
  required_rubygems_version: !ruby/object:Gem::Requirement
91
101
  requirements:
92
102
  - - ">="