universalid 0.0.1 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +929 -188
- data/Rakefile +1 -5
- data/config/default.yml +12 -0
- data/config/example.yml +45 -0
- data/contrib/active_record/base_message_pack_type.rb +11 -0
- data/contrib/active_record/base_packer.rb +130 -0
- data/contrib/active_record/base_unpacker.rb +52 -0
- data/contrib/active_record/relation_message_pack_type.rb +16 -0
- data/contrib/active_record.rb +8 -0
- data/contrib/active_support/time_with_zone_message_pack_type.rb +14 -0
- data/contrib/active_support.rb +7 -0
- data/contrib/global_id/global_id_model.rb +24 -0
- data/contrib/global_id/global_id_uid_extension.rb +36 -0
- data/contrib/global_id/message_pack_type.rb +15 -0
- data/contrib/global_id.rb +7 -0
- data/contrib/signed_global_id/message_pack_type.rb +8 -0
- data/contrib/signed_global_id.rb +7 -0
- data/contrib/tags +75 -0
- data/lib/universal_id/contrib.rb +14 -0
- data/lib/universal_id/encoder.rb +27 -0
- data/lib/universal_id/message_pack_factory.rb +37 -0
- data/lib/universal_id/message_pack_types/ruby/composites/open_struct.rb +8 -0
- data/lib/universal_id/message_pack_types/ruby/composites/set.rb +9 -0
- data/lib/universal_id/message_pack_types/ruby/composites/struct.rb +23 -0
- data/lib/universal_id/message_pack_types/ruby/scalars/complex.rb +8 -0
- data/lib/universal_id/message_pack_types/ruby/scalars/date.rb +8 -0
- data/lib/universal_id/message_pack_types/ruby/scalars/date_time.rb +8 -0
- data/lib/universal_id/message_pack_types/ruby/scalars/range.rb +20 -0
- data/lib/universal_id/message_pack_types/ruby/scalars/rational.rb +8 -0
- data/lib/universal_id/message_pack_types/ruby/scalars/regexp.rb +15 -0
- data/lib/universal_id/message_pack_types/uri/uid/type.rb +8 -0
- data/lib/universal_id/message_pack_types.rb +26 -0
- data/lib/universal_id/prepack_database_options.rb +63 -0
- data/lib/universal_id/prepack_options.rb +74 -0
- data/lib/universal_id/prepacker.rb +28 -0
- data/lib/universal_id/refinements/array_refinement.rb +17 -0
- data/lib/universal_id/refinements/hash_refinement.rb +19 -0
- data/lib/universal_id/refinements/kernel_refinement.rb +19 -0
- data/lib/universal_id/refinements/open_struct_refinement.rb +12 -0
- data/lib/universal_id/refinements/set_refinement.rb +12 -0
- data/lib/universal_id/refinements.rb +9 -0
- data/lib/universal_id/settings.rb +82 -0
- data/lib/universal_id/version.rb +1 -1
- data/lib/universal_id.rb +23 -10
- data/lib/uri/uid.rb +95 -0
- metadata +106 -28
- data/lib/universal_id/active_model_serializer.rb +0 -53
- data/lib/universal_id/config.rb +0 -18
- data/lib/universal_id/errors.rb +0 -11
- data/lib/universal_id/portable.rb +0 -24
- data/lib/universal_id/portable_hash.rb +0 -85
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
UniversalID::MessagePackFactory.register(
|
4
|
+
type: Range,
|
5
|
+
recreate_pool: false,
|
6
|
+
packer: ->(obj, packer) do
|
7
|
+
packer.write obj.first
|
8
|
+
packer.write obj.to_s.scan(/\.{2,3}/).first
|
9
|
+
packer.write obj.last
|
10
|
+
end,
|
11
|
+
unpacker: ->(unpacker) do
|
12
|
+
first = unpacker.read
|
13
|
+
operator = unpacker.read
|
14
|
+
last = unpacker.read
|
15
|
+
case operator
|
16
|
+
when ".." then first..last
|
17
|
+
when "..." then first...last
|
18
|
+
end
|
19
|
+
end
|
20
|
+
)
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
UniversalID::MessagePackFactory.register(
|
4
|
+
type: Regexp,
|
5
|
+
recreate_pool: false,
|
6
|
+
packer: ->(obj, packer) do
|
7
|
+
packer.write obj.source
|
8
|
+
packer.write obj.options
|
9
|
+
end,
|
10
|
+
unpacker: ->(unpacker) do
|
11
|
+
source = unpacker.read
|
12
|
+
options = unpacker.read
|
13
|
+
Regexp.new source, options
|
14
|
+
end
|
15
|
+
)
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# A list of all MessagePack types in the preferred registration order
|
4
|
+
#
|
5
|
+
# IMPORTANT: More specific types should be registered before more general types
|
6
|
+
# because MessagePack will use the first registered type that matches
|
7
|
+
# MessagePack scans registered type in linear order and first match wins
|
8
|
+
|
9
|
+
require_relative "contrib"
|
10
|
+
|
11
|
+
paths = %w[
|
12
|
+
message_pack_types/uri/uid/type.rb
|
13
|
+
message_pack_types/ruby/composites/set.rb
|
14
|
+
message_pack_types/ruby/composites/open_struct.rb
|
15
|
+
message_pack_types/ruby/composites/struct.rb
|
16
|
+
message_pack_types/ruby/scalars/complex.rb
|
17
|
+
message_pack_types/ruby/scalars/rational.rb
|
18
|
+
message_pack_types/ruby/scalars/date_time.rb
|
19
|
+
message_pack_types/ruby/scalars/date.rb
|
20
|
+
message_pack_types/ruby/scalars/range.rb
|
21
|
+
message_pack_types/ruby/scalars/regexp.rb
|
22
|
+
]
|
23
|
+
|
24
|
+
paths.each { |path| require_relative path }
|
25
|
+
|
26
|
+
UniversalID::MessagePackFactory.create_msgpack_pool
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class UniversalID::PrepackDatabaseOptions
|
4
|
+
def initialize(settings)
|
5
|
+
@settings = settings
|
6
|
+
end
|
7
|
+
|
8
|
+
def to_h
|
9
|
+
@settings.to_h
|
10
|
+
end
|
11
|
+
|
12
|
+
def include_keys?
|
13
|
+
!!@settings.include_keys
|
14
|
+
end
|
15
|
+
|
16
|
+
def exclude_keys?
|
17
|
+
!include_keys?
|
18
|
+
end
|
19
|
+
|
20
|
+
def include_timestamps?
|
21
|
+
!!@settings.include_timestamps
|
22
|
+
end
|
23
|
+
|
24
|
+
def exclude_timestamps?
|
25
|
+
!include_timestamps?
|
26
|
+
end
|
27
|
+
|
28
|
+
def include_unsaved_changes?
|
29
|
+
!!@settings.include_unsaved_changes
|
30
|
+
end
|
31
|
+
|
32
|
+
def exclude_unsaved_changes?
|
33
|
+
!include_unsaved_changes?
|
34
|
+
end
|
35
|
+
|
36
|
+
def descendant_depth
|
37
|
+
@settings.descendant_depth ||= 0
|
38
|
+
end
|
39
|
+
|
40
|
+
attr_writer :current_depth
|
41
|
+
|
42
|
+
def current_depth
|
43
|
+
@settings.current_depth ||= 0
|
44
|
+
end
|
45
|
+
|
46
|
+
def increment_current_depth!
|
47
|
+
@settings.current_depth ||= 0
|
48
|
+
@settings.current_depth = @settings.current_depth += 1
|
49
|
+
end
|
50
|
+
|
51
|
+
def decrement_current_depth!
|
52
|
+
@settings.current_depth ||= 0
|
53
|
+
@settings.current_depth = @settings.current_depth -= 1
|
54
|
+
end
|
55
|
+
|
56
|
+
def include_descendants?
|
57
|
+
!!@settings.include_descendants
|
58
|
+
end
|
59
|
+
|
60
|
+
def exclude_descentants?
|
61
|
+
!include_descendants?
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "prepack_database_options"
|
4
|
+
|
5
|
+
class UniversalID::PrepackOptions
|
6
|
+
attr_reader :excludes, :includes, :database_options
|
7
|
+
|
8
|
+
def initialize(options = {})
|
9
|
+
options ||= {}
|
10
|
+
@settings = UniversalID::Settings.build(**options).prepack
|
11
|
+
@database_options = UniversalID::PrepackDatabaseOptions.new(@settings.database)
|
12
|
+
@references = Set.new
|
13
|
+
@excludes ||= @settings.exclude.to_h { |key| [key.to_s, true] }
|
14
|
+
@includes ||= @settings.include.to_h { |key| [key.to_s, true] }
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_h
|
18
|
+
@settings.to_h
|
19
|
+
end
|
20
|
+
|
21
|
+
def prevent_self_reference!(object)
|
22
|
+
raise UniversalID::Prepacker::CircularReferenceError if @references.include?(object.object_id)
|
23
|
+
@references << object.object_id
|
24
|
+
end
|
25
|
+
|
26
|
+
def include_blank?
|
27
|
+
!!@settings.include_blank
|
28
|
+
end
|
29
|
+
|
30
|
+
def exclude_blank?
|
31
|
+
!include_blank?
|
32
|
+
end
|
33
|
+
|
34
|
+
def keep_key?(key)
|
35
|
+
return false if excludes[key.to_s]
|
36
|
+
includes.none? || includes[key.to_s]
|
37
|
+
end
|
38
|
+
|
39
|
+
def reject_key?(key)
|
40
|
+
excludes[key.to_s]
|
41
|
+
end
|
42
|
+
|
43
|
+
def keep_value?(value)
|
44
|
+
include_blank? || present?(value)
|
45
|
+
end
|
46
|
+
|
47
|
+
def reject_value?(value)
|
48
|
+
!keep_value?(value)
|
49
|
+
end
|
50
|
+
|
51
|
+
def keep_keypair?(key, value)
|
52
|
+
keep_key?(key) && keep_value?(value)
|
53
|
+
end
|
54
|
+
|
55
|
+
def reject_keypair?(key, value)
|
56
|
+
reject_key?(key) || reject_value?(value)
|
57
|
+
end
|
58
|
+
|
59
|
+
def blank?(value)
|
60
|
+
return true if value.nil?
|
61
|
+
return false if !!value == value # booleans
|
62
|
+
|
63
|
+
result = false
|
64
|
+
result ||= value.empty? if value.respond_to?(:empty?)
|
65
|
+
result ||= value.blank? if value.respond_to?(:blank?)
|
66
|
+
result ||= value.strip.empty? if value.is_a?(String)
|
67
|
+
result ||= value.compact.empty? if value.is_a?(Array) || value.is_a?(Hash)
|
68
|
+
result
|
69
|
+
end
|
70
|
+
|
71
|
+
def present?(value)
|
72
|
+
!blank?(value)
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "refinements"
|
4
|
+
|
5
|
+
class UniversalID::Prepacker
|
6
|
+
using UniversalID::Refinements::KernelRefinement
|
7
|
+
using UniversalID::Refinements::ArrayRefinement
|
8
|
+
using UniversalID::Refinements::HashRefinement
|
9
|
+
using UniversalID::Refinements::SetRefinement
|
10
|
+
using UniversalID::Refinements::OpenStructRefinement
|
11
|
+
|
12
|
+
class CircularReferenceError < StandardError
|
13
|
+
def initialize(message = "Prepacking not supported on self referencing objects!")
|
14
|
+
super
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class << self
|
19
|
+
def prepack(object, options = {})
|
20
|
+
options = UniversalID::PrepackOptions.new(options) unless options.is_a?(UniversalID::PrepackOptions)
|
21
|
+
|
22
|
+
return object.prepack(options) if object.respond_to?(:prepack)
|
23
|
+
|
24
|
+
object.instance_variable_set(:@_uid_prepack_options, options) unless object.frozen?
|
25
|
+
object
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module UniversalID::Refinements::ArrayRefinement
|
4
|
+
refine Array do
|
5
|
+
def prepack(options)
|
6
|
+
options.prevent_self_reference! self
|
7
|
+
|
8
|
+
copy = each_with_object([]) do |val, memo|
|
9
|
+
val = UniversalID::Prepacker.prepack(val, options)
|
10
|
+
memo << val if options.keep_value?(val)
|
11
|
+
end
|
12
|
+
|
13
|
+
copy.compact! if options.exclude_blank?
|
14
|
+
copy
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module UniversalID::Refinements::HashRefinement
|
4
|
+
refine Hash do
|
5
|
+
using UniversalID::Refinements::ArrayRefinement
|
6
|
+
|
7
|
+
def prepack(options)
|
8
|
+
options.prevent_self_reference! self
|
9
|
+
|
10
|
+
copy = each_with_object({}) do |(key, val), memo|
|
11
|
+
next unless options.keep_keypair?(key, val)
|
12
|
+
memo[key] = UniversalID::Prepacker.prepack(val, options)
|
13
|
+
end
|
14
|
+
|
15
|
+
copy.compact! if options.exclude_blank?
|
16
|
+
copy
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module UniversalID::Refinements::KernelRefinement
|
4
|
+
refine Kernel do
|
5
|
+
# Finds a constant by name, starting at the root namespace (i.e. ::Object)
|
6
|
+
def const_find(name)
|
7
|
+
return nil unless name.is_a?(String)
|
8
|
+
names = name.split("::")
|
9
|
+
constant = Object
|
10
|
+
|
11
|
+
while names.any?
|
12
|
+
value = names.shift
|
13
|
+
constant = constant.const_get(value) if constant.const_defined?(value)
|
14
|
+
end
|
15
|
+
|
16
|
+
(constant.name == name) ? constant : nil
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module UniversalID::Refinements::OpenStructRefinement
|
4
|
+
refine OpenStruct do
|
5
|
+
using UniversalID::Refinements::HashRefinement
|
6
|
+
|
7
|
+
def prepack(options)
|
8
|
+
options.prevent_self_reference! self
|
9
|
+
OpenStruct.new to_h.prepack(options)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module UniversalID::Refinements::SetRefinement
|
4
|
+
refine Set do
|
5
|
+
using UniversalID::Refinements::ArrayRefinement
|
6
|
+
|
7
|
+
def prepack(options)
|
8
|
+
options.prevent_self_reference! self
|
9
|
+
Set.new to_a.prepack(options)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module UniversalID::Refinements; end
|
4
|
+
|
5
|
+
require_relative "refinements/kernel_refinement"
|
6
|
+
require_relative "refinements/array_refinement"
|
7
|
+
require_relative "refinements/hash_refinement"
|
8
|
+
require_relative "refinements/set_refinement"
|
9
|
+
require_relative "refinements/open_struct_refinement"
|
@@ -0,0 +1,82 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "monitor"
|
4
|
+
require "singleton"
|
5
|
+
require "config"
|
6
|
+
|
7
|
+
class UniversalID::Settings
|
8
|
+
include MonitorMixin
|
9
|
+
include Singleton
|
10
|
+
|
11
|
+
DEFAULT_FILE_PATH = File.expand_path("../../config/default.yml", __dir__)
|
12
|
+
|
13
|
+
class << self
|
14
|
+
def build(**options)
|
15
|
+
instance.default_copy.tap do |settings|
|
16
|
+
options.each { |key, val| assign key, val, to: settings }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def register(...)
|
21
|
+
instance.register(...)
|
22
|
+
end
|
23
|
+
|
24
|
+
def [](key)
|
25
|
+
instance[key]
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def assign(key, value, to:)
|
31
|
+
return if value.nil?
|
32
|
+
|
33
|
+
case {key.to_sym => value}
|
34
|
+
in prepack: prepack then prepack.each { |k, v| assign k, v, to: to }
|
35
|
+
in exclude: exclude then to.prepack.exclude = exclude
|
36
|
+
in include: inc then to.prepack.include = inc
|
37
|
+
in include_blank: include_blank then to.prepack.include_blank = !!include_blank
|
38
|
+
in database: database then database.each { |k, v| assign k, v, to: to }
|
39
|
+
in include_keys: include_keys then to.prepack.database.include_keys = !!include_keys
|
40
|
+
in include_timestamps: include_timestamps then to.prepack.database.include_timestamps = !!include_timestamps
|
41
|
+
in include_unsaved_changes: include_unsaved_changes then to.prepack.database.include_unsaved_changes = !!include_unsaved_changes
|
42
|
+
in include_descendants: include_descendants then to.prepack.database.include_descendants = !!include_descendants
|
43
|
+
in descendant_depth: descendant_depth then to.prepack.database.descendant_depth = descendant_depth
|
44
|
+
else # ignore key
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def register(key, options = {})
|
50
|
+
key = key.to_s.strip.downcase.to_sym
|
51
|
+
synchronize do
|
52
|
+
raise ArgumentError, "Already registered! key: #{key}" if registry.key? key
|
53
|
+
config = case options
|
54
|
+
when String then Config.load_files(options)
|
55
|
+
when Hash then Config::Options.new(options)
|
56
|
+
when Config::Options then options
|
57
|
+
else raise ArgumentError, "Invalid options! Must be a String, Hash, or Config::Options."
|
58
|
+
end
|
59
|
+
|
60
|
+
config = self.class.build(**config) unless key == :default
|
61
|
+
registry[key] = config
|
62
|
+
self.class.define_method(key) { config }
|
63
|
+
self.class.define_method("#{key}_copy") { Marshal.load Marshal.dump(config) }
|
64
|
+
self.class.define_singleton_method(key) { instance.public_send key }
|
65
|
+
[key, config]
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def [](key)
|
70
|
+
registry[key.to_sym]
|
71
|
+
end
|
72
|
+
|
73
|
+
private
|
74
|
+
|
75
|
+
attr_reader :registry
|
76
|
+
|
77
|
+
def initialize
|
78
|
+
super
|
79
|
+
@registry = {}
|
80
|
+
register :default, DEFAULT_FILE_PATH
|
81
|
+
end
|
82
|
+
end
|
data/lib/universal_id/version.rb
CHANGED
data/lib/universal_id.rb
CHANGED
@@ -1,13 +1,26 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "
|
4
|
-
require "
|
5
|
-
require "
|
6
|
-
require "
|
7
|
-
|
3
|
+
require "date"
|
4
|
+
require "forwardable"
|
5
|
+
require "ostruct"
|
6
|
+
require "uri"
|
7
|
+
|
8
8
|
require_relative "universal_id/version"
|
9
|
-
require_relative "universal_id/
|
10
|
-
require_relative "universal_id/
|
11
|
-
require_relative "
|
12
|
-
require_relative "universal_id/
|
13
|
-
require_relative "universal_id/
|
9
|
+
require_relative "universal_id/settings"
|
10
|
+
require_relative "universal_id/encoder"
|
11
|
+
require_relative "uri/uid"
|
12
|
+
require_relative "universal_id/prepacker"
|
13
|
+
require_relative "universal_id/prepack_options"
|
14
|
+
require_relative "universal_id/message_pack_factory"
|
15
|
+
|
16
|
+
UniversalID::Settings.instance # initialize settings
|
17
|
+
|
18
|
+
module UniversalID
|
19
|
+
class << self
|
20
|
+
attr_writer :logger
|
21
|
+
|
22
|
+
def logger
|
23
|
+
@logger ||= defined?(Rails) ? Rails.logger : Logger.new(File::NULL)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/uri/uid.rb
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
unless defined?(::URI::UID) || ::URI.scheme_list.include?("UID")
|
4
|
+
|
5
|
+
module URI
|
6
|
+
class UID < ::URI::Generic
|
7
|
+
extend Forwardable
|
8
|
+
|
9
|
+
SCHEME = "uid"
|
10
|
+
HOST = "universal-id"
|
11
|
+
|
12
|
+
class << self
|
13
|
+
def parse(value)
|
14
|
+
components = ::URI.split(value.to_s)
|
15
|
+
new(*components)
|
16
|
+
end
|
17
|
+
|
18
|
+
def build_string(payload)
|
19
|
+
"#{SCHEME}://#{HOST}/#{payload}"
|
20
|
+
end
|
21
|
+
|
22
|
+
def build(object, options = {})
|
23
|
+
path = "/#{UniversalID::Encoder.encode(object, options)}"
|
24
|
+
parse "#{SCHEME}://#{HOST}#{path}"
|
25
|
+
end
|
26
|
+
|
27
|
+
# Creates a new URI::UID with the given URI components.
|
28
|
+
# SEE: https://ruby-doc.org/3.2.2/stdlibs/uri/URI/Generic.html#method-c-new
|
29
|
+
#
|
30
|
+
# @param scheme [String] the scheme component.
|
31
|
+
# @param userinfo [String] the userinfo component.
|
32
|
+
# @param host [String] the host component.
|
33
|
+
# @param port [Integer] the port component.
|
34
|
+
# @param registry [String] the registry component.
|
35
|
+
# @param path [String] the path component.
|
36
|
+
# @param opaque [String] the opaque component.
|
37
|
+
# @param query [String] the query component.
|
38
|
+
# @param fragment [String] the fragment component.
|
39
|
+
# @param parser [URI::Parser] the parser to use for the URI, defaults to DEFAULT_PARSER.
|
40
|
+
# @param arg_check [Boolean] whether to check arguments, defaults to false.
|
41
|
+
# @return [URI::UID] the new URI::UID instance.
|
42
|
+
# # @raise [URI::InvalidURIError] if the URI is malformed.
|
43
|
+
# @raise [ArgumentError] if the number of arguments is incorrect or an argument is of the wrong type.
|
44
|
+
# @raise [TypeError] if an argument is not of the expected type.
|
45
|
+
# @raise [URI::InvalidComponentError] if a component of the URI is not valid.
|
46
|
+
# @raise [URI::BadURIError] if the URI is in a bad or unexpected state.
|
47
|
+
def new(...)
|
48
|
+
super.tap do |uri|
|
49
|
+
if uri.invalid?
|
50
|
+
raise ::URI::InvalidComponentError, "Scheme must be `#{SCHEME}`" if uri.scheme != SCHEME
|
51
|
+
raise ::URI::InvalidComponentError, "Host must be `#{HOST}`" if uri.host != HOST
|
52
|
+
raise ::URI::InvalidComponentError, "Unable to parse `payload` from the path component!" if uri.payload.strip.empty?
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def payload(truncate: false)
|
59
|
+
(truncate && path.length > 80) ? "#{path[1..77]}..." : path[1..]
|
60
|
+
end
|
61
|
+
|
62
|
+
def valid?
|
63
|
+
case self
|
64
|
+
in scheme: SCHEME, host: HOST, path: p if p.size >= 8 then return true
|
65
|
+
else false
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def invalid?
|
70
|
+
!valid?
|
71
|
+
end
|
72
|
+
|
73
|
+
def decode
|
74
|
+
UniversalID::Encoder.decode(payload) if valid?
|
75
|
+
end
|
76
|
+
|
77
|
+
def deconstruct_keys(_keys)
|
78
|
+
{scheme: scheme, host: host, path: path}
|
79
|
+
end
|
80
|
+
|
81
|
+
def inspect
|
82
|
+
"#<URI::UID scheme=#{scheme}, host=#{host}, payload=#{payload truncate: true}>"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
# Register the URI scheme
|
87
|
+
if ::URI.respond_to? :register_scheme
|
88
|
+
::URI.register_scheme "UID", UID unless ::URI.scheme_list.include?("UID")
|
89
|
+
else
|
90
|
+
# shenanigans to support Ruby 3.0.X
|
91
|
+
::URI::UID = UID unless defined?(::URI::UID)
|
92
|
+
::URI.scheme_list["UID"] = UID
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|