Class: Fuzzyurl::Match

Inherits:
Object
  • Object
show all
Defined in:
lib/fuzzyurl/match.rb

Class Method Summary collapse

Class Method Details

.best_match_index(masks, url) ⇒ Object

From a list of Fuzzyurl ‘masks`, returns the index of the one which best matches `url`. Returns null if none of `masks` match.

Parameters:

  • Array (Array)

    of Fuzzyurl URL mask objects to match with.

  • Fuzzyurl (Fuzzyurl)

    URL to match.



60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/fuzzyurl/match.rb', line 60

def best_match_index(masks, url)
  best_index = nil
  best_score = -1
  masks.each_with_index do |mask, i|
    score = match(mask, url)
    if score && score > best_score
      best_score = score
      best_index = i
    end
  end
  best_index
end

.fuzzy_match(mask, value) ⇒ Object

If ‘mask` (which may contain * wildcards) matches `url` (which may not), returns 1 if `mask` and `url` match perfectly, 0 if `mask` and `url` are a wildcard match, or null otherwise.

Wildcard language:

*              matches anything
foo/*          matches "foo/" and "foo/bar/baz" but not "foo"
foo/**         matches "foo/" and "foo/bar/baz" and "foo"
*.example.com  matches "api.v1.example.com" but not "example.com"
**.example.com matches "api.v1.example.com" and "example.com"

Any other form is treated as a literal match.

Parameters:

  • mask (String)

    String mask to match with (may contain wildcards).

  • value (String)

    String value to match.



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/fuzzyurl/match.rb', line 91

def fuzzy_match(mask, value)
  return 0 if mask == "*"
  return 1 if mask == value
  return nil if !mask || !value

  if mask.index("**.") == 0
    mask_value = mask[3..-1]
    return 0 if value.end_with?(".#{mask_value}")
    return 0 if mask_value == value
    return nil
  end
  if mask.index("*") == 0
    return 0 if value.end_with?(mask[1..-1])
    return nil
  end

  rev_mask = mask.reverse
  rev_value = value.reverse

  if rev_mask.index("**/") == 0
    rev_mask_value = rev_mask[3..-1]
    return 0 if rev_value.end_with?("/#{rev_mask_value}")
    return 0 if rev_mask_value == rev_value
    return nil
  end

  if rev_mask.index("*") == 0
    return 0 if rev_value.end_with?(rev_mask[1..-1])
    return nil
  end

  nil
end

.match(mask, url) ⇒ Object

If ‘mask` (which may contain * wildcards) matches `url` (which may not), returns an integer representing how closely they match (higher is closer). If `mask` does not match `url`, returns null.

Parameters:

  • mask (Fuzzyurl)

    Fuzzyurl mask to match with

  • url (Fuzzyurl)

    Fuzzyurl URL to match



13
14
15
16
17
# File 'lib/fuzzyurl/match.rb', line 13

def match(mask, url)
  scores = match_scores(mask, url)
  return nil if scores.values.include?(nil)
  scores.values.reduce(:+)
end

.match_scores(mask, url) ⇒ Object

Returns a Fuzzyurl-like object containing values representing how well different parts of ‘mask` and `url` match. Values are integers for matches or null for no match; higher integers indicate a better match.

Parameters:

  • mask (Fuzzyurl)

    Fuzzyurl mask to match with

  • url (Fuzzyurl)

    Fuzzyurl URL to match



38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/fuzzyurl/match.rb', line 38

def match_scores(mask, url)
  url_protocol = url.protocol || Fuzzyurl::Protocols.get_protocol(url.port)
  url_port = url.port || Fuzzyurl::Protocols.get_port(url.protocol)
  {
    protocol: fuzzy_match(mask.protocol, url_protocol),
    username: fuzzy_match(mask.username, url.username),
    password: fuzzy_match(mask.password, url.password),
    hostname: fuzzy_match(mask.hostname, url.hostname),
    port: fuzzy_match(mask.port, url_port),
    path: fuzzy_match(mask.path, url.path),
    query: fuzzy_match(mask.query, url.query),
    fragment: fuzzy_match(mask.fragment, url.fragment)
  }
end

.matches?(mask, url) ⇒ Boolean

If ‘mask` (which may contain * wildcards) matches `url` (which may not), returns true; otherwise returns false.

Parameters:

  • mask (Fuzzyurl)

    Fuzzyurl mask to match with

  • url (Fuzzyurl)

    Fuzzyurl URL to match

Returns:

  • (Boolean)


26
27
28
# File 'lib/fuzzyurl/match.rb', line 26

def matches?(mask, url)
  match(mask, url) != nil
end