Class: Takagi::Discovery::CoreLinkFormat

Inherits:
Object
  • Object
show all
Defined in:
lib/takagi/discovery/core_link_format.rb,
sig/takagi/discovery/core_link_format.rbs

Overview

Builds CoRE Link Format payloads as defined in RFC 6690.

Constant Summary collapse

CONTENT_FORMAT =

Returns:

  • (40)
40

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(router, raw_query) ⇒ CoreLinkFormat

Returns a new instance of CoreLinkFormat.

Parameters:

  • router (Object)
  • raw_query (Object)


16
17
18
19
# File 'lib/takagi/discovery/core_link_format.rb', line 16

def initialize(router, raw_query)
  @router = router
  @query = parse_query(raw_query)
end

Instance Attribute Details

#queryObject (readonly)

Returns the value of attribute query.

Returns:

  • (Object)


31
32
33
# File 'lib/takagi/discovery/core_link_format.rb', line 31

def query
  @query
end

#routerObject (readonly)

Returns the value of attribute router.

Returns:

  • (Object)


31
32
33
# File 'lib/takagi/discovery/core_link_format.rb', line 31

def router
  @router
end

Class Method Details

.generate(router:, request: nil) ⇒ Object

Parameters:

  • router: (Object)
  • request: (Object, nil) (defaults to: nil)

Returns:

  • (Object)


11
12
13
14
# File 'lib/takagi/discovery/core_link_format.rb', line 11

def self.generate(router:, request: nil)
  query = request&.uri&.query
  new(router, query).generate
end

Instance Method Details

#append_attribute(attrs, name, value) ⇒ nil, untyped

Parameters:

  • attrs (Object)
  • name (Object)
  • value (Object)

Returns:

  • (nil, untyped)


98
99
100
101
102
103
104
105
106
# File 'lib/takagi/discovery/core_link_format.rb', line 98

def append_attribute(attrs, name, value)
  return if value.nil?

  if value.is_a?(Array)
    value.each { |single| attrs << %(;#{name}="#{single}") }
  else
    attrs << %(;#{name}="#{value}")
  end
end

#append_numeric_attribute(attrs, name, value) ⇒ nil, untyped

Parameters:

  • attrs (Object)
  • name (Object)
  • value (Object)

Returns:

  • (nil, untyped)


108
109
110
111
112
# File 'lib/takagi/discovery/core_link_format.rb', line 108

def append_numeric_attribute(attrs, name, value)
  return if value.nil?

  attrs << %(;#{name}=#{value})
end

#filter_resources(resources) ⇒ Object

Parameters:

  • resources (Object)

Returns:

  • (Object)


41
42
43
44
45
46
47
# File 'lib/takagi/discovery/core_link_format.rb', line 41

def filter_resources(resources)
  return resources if query.empty?

  resources.select do |entry|
    query.all? { |key, values| matches_filter?(entry, key, values) }
  end
end

#format_entry(entry) ⇒ ::String

Parameters:

  • entry (Object)

Returns:

  • (::String)


76
77
78
79
# File 'lib/takagi/discovery/core_link_format.rb', line 76

def format_entry(entry)
  attributes = link_attributes_for(entry)
  "<#{normalize_path(entry.path)}>#{attributes}"
end

#generateObject

Returns:

  • (Object)


21
22
23
24
25
26
27
# File 'lib/takagi/discovery/core_link_format.rb', line 21

def generate
  resources = router.link_format_entries
  server_entry = server_link_entry
  resources << server_entry if server_entry
  filtered = filter_resources(resources.reject { |entry| entry.path == '/.well-known/core' })
  filtered.map { |entry| format_entry(entry) }.join(',')
end

#join_attributes(attrs) ⇒ Object

Parameters:

  • attrs (Object)

Returns:

  • (Object)


114
115
116
# File 'lib/takagi/discovery/core_link_format.rb', line 114

def join_attributes(attrs)
  attrs.join
end

Parameters:

  • entry (Object)

Returns:

  • (Object)


85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/takagi/discovery/core_link_format.rb', line 85

def link_attributes_for(entry)
   = entry.

  attrs = []
  append_attribute(attrs, 'rt', [:rt]) if [:rt]
  append_attribute(attrs, 'if', [:if]) if [:if]
  append_numeric_attribute(attrs, 'ct', [:ct]) if .key?(:ct)
  append_numeric_attribute(attrs, 'sz', [:sz]) if .key?(:sz)
  append_attribute(attrs, 'title', [:title]) if [:title]
  attrs << ';obs' if [:obs]
  join_attributes(attrs)
end

#matches_filter?(entry, key, values) ⇒ Boolean

Parameters:

  • entry (Object)
  • key (Object)
  • values (Object)

Returns:

  • (Boolean)


49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/takagi/discovery/core_link_format.rb', line 49

def matches_filter?(entry, key, values)
  case key
  when 'rt' then matches_list_attribute?(entry, :rt, values)
  when 'if' then matches_list_attribute?(entry, :if, values)
  when 'ct' then matches_numeric_attribute?(entry, :ct, values)
  when 'title' then matches_string_attribute?(entry, :title, values)
  when 'sz' then matches_numeric_attribute?(entry, :sz, values)
  when 'obs' then entry.[:obs]
  when 'href' then values.any? { |val| entry.path == val }
  else false
  end
end

#matches_list_attribute?(entry, attribute, values) ⇒ Boolean

Parameters:

  • entry (Object)
  • attribute (Object)
  • values (Object)

Returns:

  • (Boolean)


62
63
64
# File 'lib/takagi/discovery/core_link_format.rb', line 62

def matches_list_attribute?(entry, attribute, values)
  Array(entry.[attribute]).any? { |item| values.include?(item.to_s) }
end

#matches_numeric_attribute?(entry, attribute, values) ⇒ Boolean

Parameters:

  • entry (Object)
  • attribute (Object)
  • values (Object)

Returns:

  • (Boolean)


66
67
68
69
# File 'lib/takagi/discovery/core_link_format.rb', line 66

def matches_numeric_attribute?(entry, attribute, values)
   = entry.[attribute]
   && values.any? { |val| .to_i == val.to_i }
end

#matches_string_attribute?(entry, attribute, values) ⇒ Boolean

Parameters:

  • entry (Object)
  • attribute (Object)
  • values (Object)

Returns:

  • (Boolean)


71
72
73
74
# File 'lib/takagi/discovery/core_link_format.rb', line 71

def matches_string_attribute?(entry, attribute, values)
   = entry.[attribute]
   && values.include?(.to_s)
end

#normalize_path(path) ⇒ Object

Parameters:

  • path (Object)

Returns:

  • (Object)


81
82
83
# File 'lib/takagi/discovery/core_link_format.rb', line 81

def normalize_path(path)
  path
end

#parse_query(raw_query) ⇒ ::Hash[untyped, untyped], untyped

Parameters:

  • raw_query (Object)

Returns:

  • (::Hash[untyped, untyped], untyped)


33
34
35
36
37
38
39
# File 'lib/takagi/discovery/core_link_format.rb', line 33

def parse_query(raw_query)
  return {} if raw_query.nil? || raw_query.empty?

  URI.decode_www_form(raw_query).each_with_object(Hash.new { |h, k| h[k] = [] }) do |(key, value), acc|
    acc[key] << (value || '')
  end
end

#server_link_entrynil, untyped

Returns:

  • (nil, untyped)


118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/takagi/discovery/core_link_format.rb', line 118

def server_link_entry
  name = Takagi.config.server_name
  return if name.nil? || name.empty?

  Takagi::Router::RouteEntry.new(
    method: 'SERVER',
    path: '/',
    block: nil,
    metadata: {
      rt: 'core.server',
      if: 'takagi.meta',
      ct: Takagi::Router::DEFAULT_CONTENT_FORMAT,
      title: name
    },
    receiver: nil
  )
end