Class: Dommy::URLPattern

Inherits:
Object
  • Object
show all
Defined in:
lib/dommy/url_pattern.rb

Overview

‘URLPattern` — pattern matching for URL components, modelled on the WICG URLPattern spec. Supports the path-like syntax familiar from Express / Sinatra / React Router:

/users/:id          → captures `id`
/docs/*             → captures the rest of the path as `0`
/api/:version+      → one-or-more segments
/api/:version?      → optional segment

Each pattern is compiled per URL component (‘protocol` / `username` / `password` / `hostname` / `port` / `pathname` / `search` / `hash`); `test(url)` returns boolean, `exec(url)` returns a result Hash whose `pathname.groups` etc. carry the captured values.

Spec: urlpattern.spec.whatwg.org/

Constant Summary collapse

COMPONENTS =
%w[protocol username password hostname port pathname search hash].freeze

Instance Method Summary collapse

Constructor Details

#initialize(init = nil, _base_url = nil) ⇒ URLPattern

Returns a new instance of URLPattern.



22
23
24
25
26
27
28
29
30
# File 'lib/dommy/url_pattern.rb', line 22

def initialize(init = nil, _base_url = nil)
  @patterns = {}
  input = init.is_a?(Hash) ? init.transform_keys(&:to_s) : {"pathname" => init.to_s}

  COMPONENTS.each do |comp|
    pattern = input[comp]
    @patterns[comp] = pattern ? compile(pattern.to_s) : compile("*")
  end
end

Instance Method Details

#__js_call__(method, args) ⇒ Object



57
58
59
60
61
62
63
64
# File 'lib/dommy/url_pattern.rb', line 57

def __js_call__(method, args)
  case method
  when "test"
    test(args[0])
  when "exec"
    exec(args[0])
  end
end

#exec(input) ⇒ Object



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/dommy/url_pattern.rb', line 36

def exec(input)
  values = extract_components(input)
  result = {}

  COMPONENTS.each do |comp|
    compiled = @patterns[comp]
    match = compiled[:regex].match(values[comp].to_s)
    return nil unless match

    groups = {}
    compiled[:names].each_with_index do |name, idx|
      groups[name] = match[idx + 1] if name
    end

    result[comp] = {"input" => values[comp].to_s, "groups" => groups}
  end

  result["inputs"] = [input]
  result
end

#test(input) ⇒ Object



32
33
34
# File 'lib/dommy/url_pattern.rb', line 32

def test(input)
  !exec(input).nil?
end