Class: URI::UID

Inherits:
Generic
  • Object
show all
Includes:
UniversalID::Extensions::GlobalIDUIDExtension
Defined in:
lib/uri/uid.rb

Constant Summary collapse

VERSION =
UniversalID::VERSION
SCHEME =
"uid"
HOST =
"universalid"
PATTERN =
/\A#{SCHEME}:\/\/#{HOST}\/[-_0-9A-Z]+#[-_0-9A-Z]+\z/io

Class Method Summary collapse

Instance Method Summary collapse

Methods included from UniversalID::Extensions::GlobalIDUIDExtension

included, #to_global_id_model

Class Method Details

.build(object, options = {}, &block) ⇒ Object



42
43
44
45
# File 'lib/uri/uid.rb', line 42

def build(object, options = {}, &block)
  path = "/#{encode(object, options, &block)}"
  parse "#{SCHEME}://#{HOST}#{path}##{fingerprint(object)}"
end

.build_string(payload, object = nil) ⇒ Object



38
39
40
# File 'lib/uri/uid.rb', line 38

def build_string(payload, object = nil)
  "#{SCHEME}://#{HOST}/#{payload}##{fingerprint(object)}"
end

.decodeObject



63
64
65
# File 'lib/uri/uid.rb', line 63

def decode(...)
  encoder.decode(...)
end

.encode(object, options = {}) ⇒ Object



58
59
60
61
# File 'lib/uri/uid.rb', line 58

def encode(object, options = {})
  return yield(object, options) if block_given?
  encoder.encode object, options
end

.encoderObject



15
16
17
# File 'lib/uri/uid.rb', line 15

def encoder
  UniversalID::Encoder
end

.fingerprint(object) ⇒ Object



19
20
21
# File 'lib/uri/uid.rb', line 19

def fingerprint(object)
  encode fingerprint_components(object)
end

.from_payload(payload, object = nil) ⇒ Object



47
48
49
50
51
52
53
54
55
56
# File 'lib/uri/uid.rb', line 47

def from_payload(payload, object = nil)
  parse(build_string(payload, object)).tap do |uid|
    # NOTE: fingerprint mismatch can happen when building from a UID payload
    #       ensure the fingerprint is correct
    if uid&.valid? && URI::UID.fingerprint(uid.decode) != uid.fingerprint
      remove_instance_variable :@decoded_fingerprint if instance_variable_defined?(:@decoded_fingerprint)
      uid.instance_variable_set :@fragment, URI::UID.build(uid.decode).fingerprint
    end
  end
end

.match?(uri) ⇒ Boolean

Returns:

  • (Boolean)


33
34
35
36
# File 'lib/uri/uid.rb', line 33

def match?(uri)
  return true if uri.is_a?(self)
  uri.to_s.match? PATTERN
end

.newURI::UID

Creates a new URI::UID with the given URI components. SEE: ruby-doc.org/3.2.2/stdlibs/uri/URI/Generic.html#method-c-new

# @raise [URI::InvalidURIError] if the URI is malformed.

Parameters:

  • scheme (String)

    the scheme component.

  • userinfo (String)

    the userinfo component.

  • host (String)

    the host component.

  • port (Integer)

    the port component.

  • registry (String)

    the registry component.

  • path (String)

    the path component.

  • opaque (String)

    the opaque component.

  • query (String)

    the query component.

  • fragment (String)

    the fragment component.

  • parser (URI::Parser)

    the parser to use for the URI, defaults to DEFAULT_PARSER.

  • arg_check (Boolean)

    whether to check arguments, defaults to false.

Returns:

  • (URI::UID)

    the new URI::UID instance.

Raises:

  • (ArgumentError)

    if the number of arguments is incorrect or an argument is of the wrong type.

  • (TypeError)

    if an argument is not of the expected type.

  • (URI::InvalidComponentError)

    if a component of the URI is not valid.

  • (URI::BadURIError)

    if the URI is in a bad or unexpected state.



87
88
89
90
91
92
93
94
95
# File 'lib/uri/uid.rb', line 87

def new(...)
  super.tap do |uri|
    if uri.invalid?
      raise ::URI::InvalidComponentError, "Scheme must be `#{SCHEME}`" if uri.scheme != SCHEME
      raise ::URI::InvalidComponentError, "Host must be `#{HOST}`" if uri.host != HOST
      raise ::URI::InvalidComponentError, "Unable to parse `payload` from the path component!" if uri.payload.strip.empty?
    end
  end
end

.parse(value) ⇒ Object



23
24
25
26
27
28
29
30
31
# File 'lib/uri/uid.rb', line 23

def parse(value)
  return nil if value.nil?
  return value if value.is_a?(self)

  value = value.to_s
  return nil if value.strip.empty?

  new(*::URI.split(value))
end

Instance Method Details

#decode(force: false) ⇒ Object



134
135
136
137
138
139
140
141
142
# File 'lib/uri/uid.rb', line 134

def decode(force: false)
  return nil unless valid?

  remove_instance_variable :@decoded if force && instance_variable_defined?(:@decoded)
  return @decoded if defined?(@decoded)

  @decoded ||= yield(decode_payload, *decode_fingerprint) if block_given?
  @decoded ||= decode_payload
end

#deconstruct_keys(_keys) ⇒ Object



144
145
146
# File 'lib/uri/uid.rb', line 144

def deconstruct_keys(_keys)
  {scheme: scheme, host: host, path: path, fragment: fragment}
end

#fingerprint(decode: false) ⇒ Object



118
119
120
121
# File 'lib/uri/uid.rb', line 118

def fingerprint(decode: false)
  return @decoded_fingerprint ||= decode_fingerprint if decode
  fragment
end

#inspectObject



148
149
150
# File 'lib/uri/uid.rb', line 148

def inspect
  "#<URI::UID payload=#{payload.truncate 40}, fingerprint=#{fingerprint.truncate 40}>"
end

#invalid?Boolean

Returns:

  • (Boolean)


130
131
132
# File 'lib/uri/uid.rb', line 130

def invalid?
  !valid?
end

#payloadObject



114
115
116
# File 'lib/uri/uid.rb', line 114

def payload
  path[1..]
end

#valid?Boolean

Returns:

  • (Boolean)


123
124
125
126
127
128
# File 'lib/uri/uid.rb', line 123

def valid?
  case self
  in scheme: SCHEME, host: HOST, path: p, fragment: _ if p.size >= 8 then return true
  else false
  end
end