These are some ideas while playing around with Sinatra, Hanami, and custom tooling.
Default Capture
Right now it is possible to set a capture value to generally apply to all captures of a pattern:
Mustermann.new("/:a/:b", capture: Integer)
You can also set it for each capture individually:
Mustermann.new("/:a/:b", capture: { a: Integer, b: :uuid })
It is not possible to set a capture value for all captures but the ones that have explicit values. It would be nice for libraries and frameworks on top of Mustermann if they could do so. Perhaps with a nil key?
Mustermann.new("/:a/:b", capture: { :a => Integer, nil => [Integer, :uuid] })
For end users this feature would probably be irrelevant, but it would be neat for building APIs that allow incremental creation of capture parameters.
Imagine the following (fictional API):
AwesomeFrameworkUsingMustermann.new do
# set :id to capture integer and uuid values in any pattern
caputre id: [Integer, :uuid]
scope "/users/:id" do
get "/projects(/:page)?", caputre: Integer do
# generated pattern would be /users/:id/projects(/:page)? with catpures = { id: [Integer, :uuid], nil => Integer }
end
end
end
Without these features, APIs built on top of Mustermann would have three alternatives:
- Don't offer incremental construction of capture rules.
- Only allow hash values to be used to begin with, no generic captures.
- Scan the pattern for captures. This is what Mustermann already does internally when performing type-native concatenation, but no proper tooling has been exposed for this other than compiling a pattern twice.
Pattern matching captures
Furthermore, we could allow adding capture rules based on a regexp or a small pattern.
Regexp approach:
Mustermann.new("/users/:user_id/posts/:post_id", capture: { /_id$/ => [Integer, :uuid] })
Or with a pattern:
Mustermann.new("/users/:user_id/posts/:post_id", capture: { "*_id" => [Integer, :uuid] })
This again isn't that much of an improvement for users instantiating patterns directly, but it comes in handy for situations where capture rules are reused.
set = Mustermann::Set.new(capture: { "(*_)?id" => Integer })
set.add "/users/:id"
set.add "/users/:user_id/posts/:id"
Implementation should be trivial. Would need to take some care of merging capture rules (as they could now overlap), but as the engine under the hood already allows nested hashes, this wouldn't be too hard either.
These are some ideas while playing around with Sinatra, Hanami, and custom tooling.
Default Capture
Right now it is possible to set a capture value to generally apply to all captures of a pattern:
You can also set it for each capture individually:
It is not possible to set a capture value for all captures but the ones that have explicit values. It would be nice for libraries and frameworks on top of Mustermann if they could do so. Perhaps with a
nilkey?For end users this feature would probably be irrelevant, but it would be neat for building APIs that allow incremental creation of capture parameters.
Imagine the following (fictional API):
Without these features, APIs built on top of Mustermann would have three alternatives:
Pattern matching captures
Furthermore, we could allow adding capture rules based on a regexp or a small pattern.
Regexp approach:
Or with a pattern:
This again isn't that much of an improvement for users instantiating patterns directly, but it comes in handy for situations where capture rules are reused.
Implementation should be trivial. Would need to take some care of merging capture rules (as they could now overlap), but as the engine under the hood already allows nested hashes, this wouldn't be too hard either.