jsi-dev 0.0.8 → 0.0.9
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/.yardopts +3 -4
- data/CHANGELOG.md +19 -0
- data/LICENSE.md +2 -3
- data/README.md +87 -43
- data/docs/{glossary.md → Glossary.md} +84 -52
- data/jsi.gemspec +1 -1
- data/lib/jsi/base/mutability.rb +48 -0
- data/lib/jsi/base/node.rb +66 -52
- data/lib/jsi/base.rb +592 -176
- data/lib/jsi/jsi_coder.rb +4 -2
- data/lib/jsi/metaschema_node/bootstrap_schema.rb +118 -59
- data/lib/jsi/metaschema_node.rb +244 -154
- data/lib/jsi/ptr.rb +45 -17
- data/lib/jsi/ref.rb +197 -0
- data/lib/jsi/registry.rb +311 -0
- data/lib/jsi/schema/cxt/child_application.rb +35 -0
- data/lib/jsi/schema/cxt/inplace_application.rb +37 -0
- data/lib/jsi/schema/cxt.rb +80 -0
- data/lib/jsi/schema/dialect.rb +137 -0
- data/lib/jsi/schema/draft04.rb +113 -5
- data/lib/jsi/schema/draft06.rb +123 -5
- data/lib/jsi/schema/draft07.rb +157 -5
- data/lib/jsi/schema/draft202012.rb +303 -0
- data/lib/jsi/schema/dynamic_anchor_map.rb +63 -0
- data/lib/jsi/schema/element.rb +69 -0
- data/lib/jsi/schema/elements/anchor.rb +13 -0
- data/lib/jsi/schema/elements/array_validation.rb +82 -0
- data/lib/jsi/schema/elements/comment.rb +10 -0
- data/lib/jsi/schema/{validation → elements}/const.rb +11 -7
- data/lib/jsi/schema/elements/contains.rb +59 -0
- data/lib/jsi/schema/elements/contains_minmax.rb +91 -0
- data/lib/jsi/schema/elements/content_encoding.rb +10 -0
- data/lib/jsi/schema/elements/content_media_type.rb +10 -0
- data/lib/jsi/schema/elements/content_schema.rb +16 -0
- data/lib/jsi/schema/elements/default.rb +11 -0
- data/lib/jsi/schema/elements/definitions.rb +19 -0
- data/lib/jsi/schema/elements/dependencies.rb +99 -0
- data/lib/jsi/schema/elements/dependent_required.rb +49 -0
- data/lib/jsi/schema/elements/dependent_schemas.rb +69 -0
- data/lib/jsi/schema/elements/dynamic_ref.rb +69 -0
- data/lib/jsi/schema/elements/enum.rb +26 -0
- data/lib/jsi/schema/elements/examples.rb +10 -0
- data/lib/jsi/schema/elements/format.rb +10 -0
- data/lib/jsi/schema/elements/id.rb +30 -0
- data/lib/jsi/schema/elements/if_then_else.rb +82 -0
- data/lib/jsi/schema/elements/info_bool.rb +10 -0
- data/lib/jsi/schema/elements/info_string.rb +10 -0
- data/lib/jsi/schema/elements/items.rb +93 -0
- data/lib/jsi/schema/elements/items_prefixed.rb +96 -0
- data/lib/jsi/schema/elements/not.rb +31 -0
- data/lib/jsi/schema/elements/numeric.rb +137 -0
- data/lib/jsi/schema/elements/numeric_draft04.rb +77 -0
- data/lib/jsi/schema/elements/object_validation.rb +55 -0
- data/lib/jsi/schema/elements/pattern.rb +35 -0
- data/lib/jsi/schema/elements/properties.rb +145 -0
- data/lib/jsi/schema/elements/property_names.rb +48 -0
- data/lib/jsi/schema/elements/ref.rb +62 -0
- data/lib/jsi/schema/elements/required.rb +34 -0
- data/lib/jsi/schema/elements/self.rb +24 -0
- data/lib/jsi/schema/elements/some_of.rb +180 -0
- data/lib/jsi/schema/elements/string_validation.rb +57 -0
- data/lib/jsi/schema/elements/type.rb +43 -0
- data/lib/jsi/schema/elements/unevaluated_items.rb +54 -0
- data/lib/jsi/schema/elements/unevaluated_properties.rb +54 -0
- data/lib/jsi/schema/elements/xschema.rb +10 -0
- data/lib/jsi/schema/elements/xvocabulary.rb +10 -0
- data/lib/jsi/schema/elements.rb +101 -0
- data/lib/jsi/schema/issue.rb +3 -4
- data/lib/jsi/schema/schema_ancestor_node.rb +105 -52
- data/lib/jsi/schema/vocabulary.rb +36 -0
- data/lib/jsi/schema.rb +598 -383
- data/lib/jsi/schema_classes.rb +195 -141
- data/lib/jsi/schema_set.rb +85 -128
- data/lib/jsi/set.rb +23 -0
- data/lib/jsi/simple_wrap.rb +14 -17
- data/lib/jsi/struct.rb +57 -0
- data/lib/jsi/uri.rb +40 -0
- data/lib/jsi/util/private/memo_map.rb +9 -13
- data/lib/jsi/util/private.rb +59 -31
- data/lib/jsi/util/typelike.rb +19 -60
- data/lib/jsi/util.rb +53 -34
- data/lib/jsi/validation/error.rb +45 -2
- data/lib/jsi/validation/result.rb +121 -90
- data/lib/jsi/validation.rb +1 -6
- data/lib/jsi/version.rb +1 -1
- data/lib/jsi.rb +170 -36
- data/lib/schemas/json-schema.org/draft/2020-12/schema.rb +62 -0
- data/lib/schemas/json-schema.org/draft-04/schema.rb +60 -109
- data/lib/schemas/json-schema.org/draft-06/schema.rb +53 -108
- data/lib/schemas/json-schema.org/draft-07/schema.rb +63 -127
- data/readme.rb +4 -4
- data/{resources}/schemas/2020-12_strict.json +19 -0
- data/{resources}/schemas/json-schema.org/draft/2020-12/meta/applicator.json +48 -0
- data/{resources}/schemas/json-schema.org/draft/2020-12/meta/content.json +17 -0
- data/{resources}/schemas/json-schema.org/draft/2020-12/meta/core.json +51 -0
- data/{resources}/schemas/json-schema.org/draft/2020-12/meta/format-annotation.json +14 -0
- data/{resources}/schemas/json-schema.org/draft/2020-12/meta/format-assertion.json +14 -0
- data/{resources}/schemas/json-schema.org/draft/2020-12/meta/meta-data.json +37 -0
- data/{resources}/schemas/json-schema.org/draft/2020-12/meta/unevaluated.json +15 -0
- data/{resources}/schemas/json-schema.org/draft/2020-12/meta/validation.json +98 -0
- data/{resources}/schemas/json-schema.org/draft/2020-12/schema.json +58 -0
- metadata +73 -52
- data/lib/jsi/metaschema.rb +0 -6
- data/lib/jsi/schema/application/child_application/contains.rb +0 -25
- data/lib/jsi/schema/application/child_application/draft04.rb +0 -21
- data/lib/jsi/schema/application/child_application/draft06.rb +0 -28
- data/lib/jsi/schema/application/child_application/draft07.rb +0 -28
- data/lib/jsi/schema/application/child_application/items.rb +0 -18
- data/lib/jsi/schema/application/child_application/properties.rb +0 -25
- data/lib/jsi/schema/application/child_application.rb +0 -13
- data/lib/jsi/schema/application/draft04.rb +0 -8
- data/lib/jsi/schema/application/draft06.rb +0 -8
- data/lib/jsi/schema/application/draft07.rb +0 -8
- data/lib/jsi/schema/application/inplace_application/dependencies.rb +0 -28
- data/lib/jsi/schema/application/inplace_application/draft04.rb +0 -25
- data/lib/jsi/schema/application/inplace_application/draft06.rb +0 -26
- data/lib/jsi/schema/application/inplace_application/draft07.rb +0 -32
- data/lib/jsi/schema/application/inplace_application/ifthenelse.rb +0 -20
- data/lib/jsi/schema/application/inplace_application/ref.rb +0 -18
- data/lib/jsi/schema/application/inplace_application/someof.rb +0 -44
- data/lib/jsi/schema/application/inplace_application.rb +0 -14
- data/lib/jsi/schema/application.rb +0 -12
- data/lib/jsi/schema/ref.rb +0 -183
- data/lib/jsi/schema/validation/array.rb +0 -69
- data/lib/jsi/schema/validation/contains.rb +0 -25
- data/lib/jsi/schema/validation/dependencies.rb +0 -49
- data/lib/jsi/schema/validation/draft04/minmax.rb +0 -91
- data/lib/jsi/schema/validation/draft04.rb +0 -110
- data/lib/jsi/schema/validation/draft06.rb +0 -120
- data/lib/jsi/schema/validation/draft07.rb +0 -157
- data/lib/jsi/schema/validation/enum.rb +0 -25
- data/lib/jsi/schema/validation/ifthenelse.rb +0 -46
- data/lib/jsi/schema/validation/items.rb +0 -54
- data/lib/jsi/schema/validation/not.rb +0 -20
- data/lib/jsi/schema/validation/numeric.rb +0 -121
- data/lib/jsi/schema/validation/object.rb +0 -45
- data/lib/jsi/schema/validation/pattern.rb +0 -34
- data/lib/jsi/schema/validation/properties.rb +0 -101
- data/lib/jsi/schema/validation/property_names.rb +0 -32
- data/lib/jsi/schema/validation/ref.rb +0 -40
- data/lib/jsi/schema/validation/required.rb +0 -27
- data/lib/jsi/schema/validation/someof.rb +0 -90
- data/lib/jsi/schema/validation/string.rb +0 -47
- data/lib/jsi/schema/validation/type.rb +0 -49
- data/lib/jsi/schema/validation.rb +0 -49
- data/lib/jsi/schema_registry.rb +0 -190
- data/lib/jsi/util/private/attr_struct.rb +0 -130
data/lib/jsi/schema_registry.rb
DELETED
|
@@ -1,190 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module JSI
|
|
4
|
-
class SchemaRegistry
|
|
5
|
-
# an exception raised when an attempt is made to register a resource using a URI which is already
|
|
6
|
-
# registered with another resource
|
|
7
|
-
class Collision < StandardError
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
# an exception raised when an attempt is made to access (register or find) a resource of the
|
|
11
|
-
# registry using a URI which is not absolute (it is a relative URI or it contains a fragment)
|
|
12
|
-
class NonAbsoluteURI < StandardError
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
# an exception raised when a URI we are looking for has not been registered
|
|
16
|
-
class ResourceNotFound < StandardError
|
|
17
|
-
attr_accessor :uri
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
def initialize
|
|
21
|
-
@resources = {}
|
|
22
|
-
@autoload_uris = {}
|
|
23
|
-
@resources_mutex = Mutex.new
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
# registers the given resource and/or schema resources it contains in the registry.
|
|
27
|
-
#
|
|
28
|
-
# each descendent node of the resource (including the resource itself) is registered if it is a schema
|
|
29
|
-
# that has an absolute URI (generally defined by the '$id' keyword).
|
|
30
|
-
#
|
|
31
|
-
# the given resource itself will be registered, whether or not it is a schema, if it is the root
|
|
32
|
-
# of its document and was instantiated with the option `uri` specified.
|
|
33
|
-
#
|
|
34
|
-
# @param resource [JSI::Base] a JSI containing resources to register
|
|
35
|
-
# @return [void]
|
|
36
|
-
def register(resource)
|
|
37
|
-
unless resource.is_a?(JSI::Base)
|
|
38
|
-
raise(ArgumentError, "resource must be a JSI::Base. got: #{resource.pretty_inspect.chomp}")
|
|
39
|
-
end
|
|
40
|
-
unless resource.is_a?(JSI::Schema) || resource.jsi_ptr.root?
|
|
41
|
-
# unsure, should this be allowed? the given JSI is not a "resource" as we define it, but
|
|
42
|
-
# if this check is removed it will just register any resources (schemas) below the given JSI.
|
|
43
|
-
raise(ArgumentError, "undefined behavior: registration of a JSI which is not a schema and is not at the root of a document")
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
# allow for registration of resources at the root of a document whether or not they are schemas.
|
|
47
|
-
# jsi_schema_base_uri at the root comes from the `uri` parameter to new_jsi / new_schema.
|
|
48
|
-
if resource.jsi_schema_base_uri && resource.jsi_ptr.root?
|
|
49
|
-
register_single(resource.jsi_schema_base_uri, resource)
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
resource.jsi_each_descendent_node do |node|
|
|
53
|
-
if node.is_a?(JSI::Schema) && node.schema_absolute_uri
|
|
54
|
-
register_single(node.schema_absolute_uri, node)
|
|
55
|
-
end
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
nil
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
# takes a URI identifying a resource to be loaded by the given block
|
|
62
|
-
# when a reference to the URI is followed.
|
|
63
|
-
#
|
|
64
|
-
# for example:
|
|
65
|
-
#
|
|
66
|
-
# JSI.schema_registry.autoload_uri('http://example.com/schema.json') do
|
|
67
|
-
# JSI.new_schema({
|
|
68
|
-
# '$schema' => 'http://json-schema.org/draft-07/schema#',
|
|
69
|
-
# '$id' => 'http://example.com/schema.json',
|
|
70
|
-
# 'title' => 'my schema',
|
|
71
|
-
# })
|
|
72
|
-
# end
|
|
73
|
-
#
|
|
74
|
-
# the block would normally load JSON from the filesystem or similar.
|
|
75
|
-
#
|
|
76
|
-
# @param uri [Addressable::URI]
|
|
77
|
-
# @yieldreturn [JSI::Base] a JSI instance containing the resource identified by the given uri
|
|
78
|
-
# @return [void]
|
|
79
|
-
def autoload_uri(uri, &block)
|
|
80
|
-
uri = ensure_uri_absolute(uri)
|
|
81
|
-
mutating
|
|
82
|
-
unless block
|
|
83
|
-
raise(ArgumentError, ["#{SchemaRegistry}#autoload_uri must be invoked with a block", "URI: #{uri}"].join("\n"))
|
|
84
|
-
end
|
|
85
|
-
if @autoload_uris.key?(uri)
|
|
86
|
-
raise(Collision, ["already registered URI for autoload", "URI: #{uri}", "loader: #{@autoload_uris[uri]}"].join("\n"))
|
|
87
|
-
end
|
|
88
|
-
@autoload_uris[uri] = block
|
|
89
|
-
nil
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
# @param uri [Addressable::URI, #to_str]
|
|
93
|
-
# @return [JSI::Base]
|
|
94
|
-
# @raise [JSI::SchemaRegistry::ResourceNotFound]
|
|
95
|
-
def find(uri)
|
|
96
|
-
uri = ensure_uri_absolute(uri)
|
|
97
|
-
if @autoload_uris.key?(uri)
|
|
98
|
-
autoloaded = @autoload_uris[uri].call
|
|
99
|
-
register(autoloaded)
|
|
100
|
-
@autoload_uris.delete(uri)
|
|
101
|
-
end
|
|
102
|
-
if !@resources.key?(uri)
|
|
103
|
-
if autoloaded
|
|
104
|
-
msg = [
|
|
105
|
-
"URI #{uri} was registered with autoload_uri but the result did not contain a resource with that URI.",
|
|
106
|
-
"the resource resulting from autoload_uri was:",
|
|
107
|
-
autoloaded.pretty_inspect.chomp,
|
|
108
|
-
]
|
|
109
|
-
else
|
|
110
|
-
msg = ["URI #{uri} is not registered. registered URIs:", *(@resources.keys | @autoload_uris.keys)]
|
|
111
|
-
end
|
|
112
|
-
raise(ResourceNotFound.new(msg.join("\n")).tap { |e| e.uri = uri })
|
|
113
|
-
end
|
|
114
|
-
@resources[uri]
|
|
115
|
-
end
|
|
116
|
-
|
|
117
|
-
def inspect
|
|
118
|
-
[
|
|
119
|
-
'#<JSI::SchemaRegistry',
|
|
120
|
-
*[['autoload', @autoload_uris.keys], ['resources', @resources.keys]].map do |label, uris|
|
|
121
|
-
[
|
|
122
|
-
" #{label} (#{uris.size})#{uris.empty? ? "" : ":"}",
|
|
123
|
-
*uris.map do |uri|
|
|
124
|
-
" #{uri}"
|
|
125
|
-
end,
|
|
126
|
-
]
|
|
127
|
-
end.inject([], &:+),
|
|
128
|
-
'>',
|
|
129
|
-
].join("\n").freeze
|
|
130
|
-
end
|
|
131
|
-
|
|
132
|
-
alias_method :to_s, :inspect
|
|
133
|
-
|
|
134
|
-
def dup
|
|
135
|
-
self.class.new.tap do |reg|
|
|
136
|
-
@resources.each do |uri, resource|
|
|
137
|
-
reg.register_single(uri, resource)
|
|
138
|
-
end
|
|
139
|
-
@autoload_uris.each do |uri, autoload|
|
|
140
|
-
reg.autoload_uri(uri, &autoload)
|
|
141
|
-
end
|
|
142
|
-
end
|
|
143
|
-
end
|
|
144
|
-
|
|
145
|
-
def freeze
|
|
146
|
-
@resources.freeze
|
|
147
|
-
@autoload_uris.freeze
|
|
148
|
-
@resources_mutex = nil
|
|
149
|
-
super
|
|
150
|
-
end
|
|
151
|
-
|
|
152
|
-
protected
|
|
153
|
-
# @param uri [Addressable::URI]
|
|
154
|
-
# @param resource [JSI::Base]
|
|
155
|
-
# @return [void]
|
|
156
|
-
def register_single(uri, resource)
|
|
157
|
-
mutating
|
|
158
|
-
@resources_mutex.synchronize do
|
|
159
|
-
ensure_uri_absolute(uri)
|
|
160
|
-
if @resources.key?(uri)
|
|
161
|
-
if @resources[uri] != resource
|
|
162
|
-
raise(Collision, "URI collision on #{uri}.\nexisting:\n#{@resources[uri].pretty_inspect.chomp}\nnew:\n#{resource.pretty_inspect.chomp}")
|
|
163
|
-
end
|
|
164
|
-
else
|
|
165
|
-
@resources[uri] = resource
|
|
166
|
-
end
|
|
167
|
-
end
|
|
168
|
-
nil
|
|
169
|
-
end
|
|
170
|
-
|
|
171
|
-
private
|
|
172
|
-
|
|
173
|
-
def ensure_uri_absolute(uri)
|
|
174
|
-
uri = Util.uri(uri)
|
|
175
|
-
if uri.fragment
|
|
176
|
-
raise(NonAbsoluteURI, "#{self.class} only registers absolute URIs. cannot access URI with fragment: #{uri}")
|
|
177
|
-
end
|
|
178
|
-
if uri.relative?
|
|
179
|
-
raise(NonAbsoluteURI, "#{self.class} only registers absolute URIs. cannot access relative URI: #{uri}")
|
|
180
|
-
end
|
|
181
|
-
uri
|
|
182
|
-
end
|
|
183
|
-
|
|
184
|
-
def mutating
|
|
185
|
-
if frozen?
|
|
186
|
-
raise(FrozenError, "cannot modify frozen #{self.class}")
|
|
187
|
-
end
|
|
188
|
-
end
|
|
189
|
-
end
|
|
190
|
-
end
|
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module JSI
|
|
4
|
-
module Util::Private
|
|
5
|
-
# like a Struct, but stores all the attributes in one @attributes Hash, instead of individual instance
|
|
6
|
-
# variables for each attribute.
|
|
7
|
-
# this tends to be easier to work with and more flexible. keys which are symbols are converted to strings.
|
|
8
|
-
class AttrStruct
|
|
9
|
-
class AttrStructError < StandardError
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
class UndefinedAttributeKey < AttrStructError
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
class << self
|
|
16
|
-
# creates a AttrStruct subclass with the given attribute keys.
|
|
17
|
-
# @param attribute_keys [Enumerable<String, Symbol>]
|
|
18
|
-
def subclass(*attribute_keys)
|
|
19
|
-
bad = attribute_keys.reject { |key| key.respond_to?(:to_str) || key.is_a?(Symbol) }
|
|
20
|
-
unless bad.empty?
|
|
21
|
-
raise ArgumentError, "attribute keys must be String or Symbol; got keys: #{bad.map(&:inspect).join(', ')}"
|
|
22
|
-
end
|
|
23
|
-
attribute_keys = attribute_keys.map { |key| convert_key(key) }
|
|
24
|
-
|
|
25
|
-
all_attribute_keys = (self.attribute_keys + attribute_keys).freeze
|
|
26
|
-
|
|
27
|
-
Class.new(self).tap do |klass|
|
|
28
|
-
klass.define_singleton_method(:attribute_keys) { all_attribute_keys }
|
|
29
|
-
|
|
30
|
-
attribute_keys.each do |attribute_key|
|
|
31
|
-
# reader
|
|
32
|
-
klass.send(:define_method, attribute_key) do
|
|
33
|
-
@attributes[attribute_key]
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
# writer
|
|
37
|
-
klass.send(:define_method, "#{attribute_key}=") do |value|
|
|
38
|
-
@attributes[attribute_key] = value
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
alias_method :[], :subclass
|
|
45
|
-
|
|
46
|
-
# the attribute keys defined for this class
|
|
47
|
-
# @return [Set<String>]
|
|
48
|
-
def attribute_keys
|
|
49
|
-
# empty for AttrStruct itself; redefined on each subclass
|
|
50
|
-
Util::Private::EMPTY_SET
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
# returns a frozen string, given a string or symbol.
|
|
54
|
-
# returns anything else as-is for the caller to handle.
|
|
55
|
-
# @api private
|
|
56
|
-
def convert_key(key)
|
|
57
|
-
# TODO use Symbol#name when available on supported rubies
|
|
58
|
-
key.is_a?(Symbol) ? key.to_s.freeze : key.frozen? ? key : key.is_a?(String) ? key.dup.freeze : key
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
def initialize(attributes = {})
|
|
63
|
-
unless attributes.respond_to?(:to_hash)
|
|
64
|
-
raise(TypeError, "expected attributes to be a Hash; got: #{attributes.inspect}")
|
|
65
|
-
end
|
|
66
|
-
@attributes = {}
|
|
67
|
-
attributes.to_hash.each do |k, v|
|
|
68
|
-
@attributes[self.class.convert_key(k)] = v
|
|
69
|
-
end
|
|
70
|
-
bad = @attributes.keys.reject { |k| attribute_keys.include?(k) }
|
|
71
|
-
unless bad.empty?
|
|
72
|
-
raise UndefinedAttributeKey, "undefined attribute keys: #{bad.map(&:inspect).join(', ')}"
|
|
73
|
-
end
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
def [](key)
|
|
77
|
-
@attributes[key.is_a?(Symbol) ? key.to_s : key]
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
def []=(key, value)
|
|
81
|
-
key = self.class.convert_key(key)
|
|
82
|
-
unless attribute_keys.include?(key)
|
|
83
|
-
raise UndefinedAttributeKey, "undefined attribute key: #{key.inspect}"
|
|
84
|
-
end
|
|
85
|
-
@attributes[key] = value
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
# @return [String]
|
|
89
|
-
def inspect
|
|
90
|
-
-"\#<#{self.class.name}#{@attributes.map { |k, v| " #{k}: #{v.inspect}" }.join(',')}>"
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
alias_method :to_s, :inspect
|
|
94
|
-
|
|
95
|
-
# pretty-prints a representation of self to the given printer
|
|
96
|
-
# @return [void]
|
|
97
|
-
def pretty_print(q)
|
|
98
|
-
q.text '#<'
|
|
99
|
-
q.text self.class.name
|
|
100
|
-
q.group_sub {
|
|
101
|
-
q.nest(2) {
|
|
102
|
-
q.breakable(@attributes.empty? ? '' : ' ')
|
|
103
|
-
q.seplist(@attributes, nil, :each_pair) { |k, v|
|
|
104
|
-
q.group {
|
|
105
|
-
q.text k
|
|
106
|
-
q.text ': '
|
|
107
|
-
q.pp v
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
q.breakable ''
|
|
113
|
-
q.text '>'
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
# (see AttrStruct.attribute_keys)
|
|
117
|
-
def attribute_keys
|
|
118
|
-
self.class.attribute_keys
|
|
119
|
-
end
|
|
120
|
-
|
|
121
|
-
include FingerprintHash
|
|
122
|
-
|
|
123
|
-
# see {Util::Private::FingerprintHash}
|
|
124
|
-
# @api private
|
|
125
|
-
def jsi_fingerprint
|
|
126
|
-
{class: self.class, attributes: @attributes}
|
|
127
|
-
end
|
|
128
|
-
end
|
|
129
|
-
end
|
|
130
|
-
end
|