lutaml-model 0.7.3 → 0.7.5
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/.envrc +1 -0
- data/.github/workflows/release.yml +3 -0
- data/.gitignore +6 -1
- data/.irbrc +1 -0
- data/.pryrc +1 -0
- data/.rubocop_todo.yml +25 -52
- data/README.adoc +2177 -192
- data/docs/custom_registers.adoc +228 -0
- data/docs/schema_generation.adoc +898 -0
- data/docs/schema_import.adoc +364 -0
- data/flake.lock +114 -0
- data/flake.nix +103 -0
- data/lib/lutaml/model/attribute.rb +230 -94
- data/lib/lutaml/model/choice.rb +30 -0
- data/lib/lutaml/model/collection.rb +194 -0
- data/lib/lutaml/model/comparable_model.rb +3 -3
- data/lib/lutaml/model/config.rb +26 -3
- data/lib/lutaml/model/constants.rb +2 -0
- data/lib/lutaml/model/error/element_count_out_of_range_error.rb +29 -0
- data/lib/lutaml/model/error/invalid_attribute_name_error.rb +15 -0
- data/lib/lutaml/model/error/invalid_attribute_options_error.rb +16 -0
- data/lib/lutaml/model/error/invalid_choice_range_error.rb +3 -5
- data/lib/lutaml/model/error/register/not_registrable_class_error.rb +11 -0
- data/lib/lutaml/model/error/type/invalid_value_error.rb +5 -3
- data/lib/lutaml/model/error/type/max_bound_error.rb +20 -0
- data/lib/lutaml/model/error/type/max_length_error.rb +20 -0
- data/lib/lutaml/model/error/type/min_bound_error.rb +20 -0
- data/lib/lutaml/model/error/type/min_length_error.rb +20 -0
- data/lib/lutaml/model/error/type/pattern_not_matched_error.rb +18 -0
- data/lib/lutaml/model/error/validation_failed_error.rb +9 -0
- data/lib/lutaml/model/error.rb +10 -0
- data/lib/lutaml/model/errors.rb +36 -0
- data/lib/lutaml/model/format_registry.rb +5 -2
- data/lib/lutaml/model/global_register.rb +41 -0
- data/lib/lutaml/model/{hash.rb → hash_adapter.rb} +5 -5
- data/lib/lutaml/model/jsonl/document.rb +14 -0
- data/lib/lutaml/model/jsonl/mapping.rb +19 -0
- data/lib/lutaml/model/jsonl/mapping_rule.rb +9 -0
- data/lib/lutaml/model/jsonl/standard_adapter.rb +33 -0
- data/lib/lutaml/model/jsonl/transform.rb +19 -0
- data/lib/lutaml/model/jsonl.rb +21 -0
- data/lib/lutaml/model/key_value_document.rb +3 -2
- data/lib/lutaml/model/mapping/key_value_mapping.rb +64 -4
- data/lib/lutaml/model/mapping/key_value_mapping_rule.rb +4 -0
- data/lib/lutaml/model/mapping/mapping_rule.rb +8 -3
- data/lib/lutaml/model/register.rb +105 -0
- data/lib/lutaml/model/registrable.rb +6 -0
- data/lib/lutaml/model/schema/base_schema.rb +64 -0
- data/lib/lutaml/model/schema/decorators/attribute.rb +114 -0
- data/lib/lutaml/model/schema/decorators/choices.rb +31 -0
- data/lib/lutaml/model/schema/decorators/class_definition.rb +85 -0
- data/lib/lutaml/model/schema/decorators/definition_collection.rb +97 -0
- data/lib/lutaml/model/schema/generator/definition.rb +53 -0
- data/lib/lutaml/model/schema/generator/definitions_collection.rb +81 -0
- data/lib/lutaml/model/schema/generator/properties_collection.rb +63 -0
- data/lib/lutaml/model/schema/generator/property.rb +110 -0
- data/lib/lutaml/model/schema/generator/ref.rb +24 -0
- data/lib/lutaml/model/schema/helpers/template_helper.rb +49 -0
- data/lib/lutaml/model/schema/json_schema.rb +42 -49
- data/lib/lutaml/model/schema/relaxng_schema.rb +14 -10
- data/lib/lutaml/model/schema/renderer.rb +36 -0
- data/lib/lutaml/model/schema/shared_methods.rb +24 -0
- data/lib/lutaml/model/schema/templates/model.erb +9 -0
- data/lib/lutaml/model/schema/xml_compiler/attribute.rb +85 -0
- data/lib/lutaml/model/schema/xml_compiler/attribute_group.rb +45 -0
- data/lib/lutaml/model/schema/xml_compiler/choice.rb +65 -0
- data/lib/lutaml/model/schema/xml_compiler/complex_content.rb +27 -0
- data/lib/lutaml/model/schema/xml_compiler/complex_content_restriction.rb +34 -0
- data/lib/lutaml/model/schema/xml_compiler/complex_type.rb +136 -0
- data/lib/lutaml/model/schema/xml_compiler/element.rb +104 -0
- data/lib/lutaml/model/schema/xml_compiler/group.rb +97 -0
- data/lib/lutaml/model/schema/xml_compiler/restriction.rb +101 -0
- data/lib/lutaml/model/schema/xml_compiler/sequence.rb +50 -0
- data/lib/lutaml/model/schema/xml_compiler/simple_content.rb +36 -0
- data/lib/lutaml/model/schema/xml_compiler/simple_type.rb +189 -0
- data/lib/lutaml/model/schema/xml_compiler.rb +231 -587
- data/lib/lutaml/model/schema/xsd_schema.rb +12 -8
- data/lib/lutaml/model/schema/yaml_schema.rb +41 -35
- data/lib/lutaml/model/schema.rb +1 -0
- data/lib/lutaml/model/sequence.rb +60 -30
- data/lib/lutaml/model/serialize.rb +175 -53
- data/lib/lutaml/model/services/base.rb +11 -0
- data/lib/lutaml/model/services/logger.rb +2 -2
- data/lib/lutaml/model/services/rule_value_extractor.rb +92 -0
- data/lib/lutaml/model/services/type/validator/number.rb +25 -0
- data/lib/lutaml/model/services/type/validator/string.rb +52 -0
- data/lib/lutaml/model/services/type/validator.rb +43 -0
- data/lib/lutaml/model/services/validator.rb +145 -0
- data/lib/lutaml/model/services.rb +3 -0
- data/lib/lutaml/model/transform/key_value_transform.rb +60 -50
- data/lib/lutaml/model/transform/xml_transform.rb +46 -57
- data/lib/lutaml/model/transform.rb +22 -8
- data/lib/lutaml/model/type/boolean.rb +1 -1
- data/lib/lutaml/model/type/date.rb +1 -1
- data/lib/lutaml/model/type/date_time.rb +1 -1
- data/lib/lutaml/model/type/decimal.rb +11 -9
- data/lib/lutaml/model/type/float.rb +2 -1
- data/lib/lutaml/model/type/integer.rb +24 -21
- data/lib/lutaml/model/type/string.rb +4 -2
- data/lib/lutaml/model/type/time.rb +1 -1
- data/lib/lutaml/model/type/time_without_date.rb +1 -1
- data/lib/lutaml/model/type/value.rb +5 -1
- data/lib/lutaml/model/type.rb +5 -2
- data/lib/lutaml/model/utils.rb +30 -8
- data/lib/lutaml/model/validation.rb +6 -4
- data/lib/lutaml/model/version.rb +1 -1
- data/lib/lutaml/model/xml/document.rb +37 -19
- data/lib/lutaml/model/xml/mapping.rb +74 -13
- data/lib/lutaml/model/xml/mapping_rule.rb +10 -2
- data/lib/lutaml/model/xml/nokogiri_adapter.rb +5 -3
- data/lib/lutaml/model/xml/oga/element.rb +4 -1
- data/lib/lutaml/model/xml/oga_adapter.rb +4 -3
- data/lib/lutaml/model/xml/ox_adapter.rb +20 -6
- data/lib/lutaml/model/xml/xml_element.rb +3 -28
- data/lib/lutaml/model/xml_adapter/element.rb +1 -1
- data/lib/lutaml/model/xml_adapter/nokogiri_adapter.rb +1 -1
- data/lib/lutaml/model/xml_adapter/oga_adapter.rb +1 -1
- data/lib/lutaml/model/xml_adapter/ox_adapter.rb +1 -1
- data/lib/lutaml/model/yamls/document.rb +14 -0
- data/lib/lutaml/model/yamls/mapping.rb +19 -0
- data/lib/lutaml/model/yamls/mapping_rule.rb +9 -0
- data/lib/lutaml/model/yamls/standard_adapter.rb +34 -0
- data/lib/lutaml/model/yamls/transform.rb +19 -0
- data/lib/lutaml/model/yamls.rb +21 -0
- data/lib/lutaml/model.rb +7 -31
- data/spec/benchmarks/xml_parsing_benchmark_spec.rb +4 -5
- data/spec/fixtures/xml/advanced_test_schema.xsd +134 -0
- data/spec/fixtures/xml/examples/nested_categories.xml +55 -0
- data/spec/fixtures/xml/examples/valid_catalog.xml +43 -0
- data/spec/fixtures/xml/product_catalog.xsd +151 -0
- data/spec/fixtures/xml/specifications_schema.xsd +38 -0
- data/spec/lutaml/model/attribute_collection_spec.rb +101 -0
- data/spec/lutaml/model/attribute_spec.rb +41 -44
- data/spec/lutaml/model/choice_spec.rb +44 -0
- data/spec/lutaml/model/custom_collection_spec.rb +830 -0
- data/spec/lutaml/model/custom_model_spec.rb +15 -3
- data/spec/lutaml/model/defaults_spec.rb +5 -1
- data/spec/lutaml/model/global_register_spec.rb +108 -0
- data/spec/lutaml/model/group_spec.rb +9 -3
- data/spec/lutaml/model/jsonl/standard_adapter_spec.rb +91 -0
- data/spec/lutaml/model/jsonl_spec.rb +229 -0
- data/spec/lutaml/model/multiple_mapping_spec.rb +1 -1
- data/spec/lutaml/model/register/key_value_spec.rb +275 -0
- data/spec/lutaml/model/register/xml_spec.rb +187 -0
- data/spec/lutaml/model/register_spec.rb +147 -0
- data/spec/lutaml/model/rule_value_extractor_spec.rb +162 -0
- data/spec/lutaml/model/schema/generator/definitions_collection_spec.rb +120 -0
- data/spec/lutaml/model/schema/json_schema_spec.rb +412 -51
- data/spec/lutaml/model/schema/json_schema_to_models_spec.rb +383 -0
- data/spec/lutaml/model/schema/xml_compiler/attribute_group_spec.rb +65 -0
- data/spec/lutaml/model/schema/xml_compiler/attribute_spec.rb +63 -0
- data/spec/lutaml/model/schema/xml_compiler/choice_spec.rb +71 -0
- data/spec/lutaml/model/schema/xml_compiler/complex_content_restriction_spec.rb +55 -0
- data/spec/lutaml/model/schema/xml_compiler/complex_content_spec.rb +37 -0
- data/spec/lutaml/model/schema/xml_compiler/complex_type_spec.rb +173 -0
- data/spec/lutaml/model/schema/xml_compiler/element_spec.rb +63 -0
- data/spec/lutaml/model/schema/xml_compiler/group_spec.rb +86 -0
- data/spec/lutaml/model/schema/xml_compiler/restriction_spec.rb +76 -0
- data/spec/lutaml/model/schema/xml_compiler/sequence_spec.rb +59 -0
- data/spec/lutaml/model/schema/xml_compiler/simple_content_spec.rb +55 -0
- data/spec/lutaml/model/schema/xml_compiler/simple_type_spec.rb +181 -0
- data/spec/lutaml/model/schema/xml_compiler_spec.rb +503 -1804
- data/spec/lutaml/model/schema/yaml_schema_spec.rb +249 -26
- data/spec/lutaml/model/sequence_spec.rb +36 -0
- data/spec/lutaml/model/serializable_spec.rb +31 -0
- data/spec/lutaml/model/type_spec.rb +8 -4
- data/spec/lutaml/model/utils_spec.rb +3 -3
- data/spec/lutaml/model/xml/derived_attributes_spec.rb +1 -1
- data/spec/lutaml/model/xml/xml_element_spec.rb +7 -1
- data/spec/lutaml/model/xml_adapter/xml_namespace_spec.rb +6 -6
- data/spec/lutaml/model/xml_adapter_spec.rb +24 -0
- data/spec/lutaml/model/xml_mapping_rule_spec.rb +11 -4
- data/spec/lutaml/model/xml_mapping_spec.rb +1 -1
- data/spec/lutaml/model/yamls/standard_adapter_spec.rb +183 -0
- data/spec/lutaml/model/yamls_spec.rb +294 -0
- data/spec/spec_helper.rb +1 -0
- metadata +105 -9
- data/lib/lutaml/model/schema/templates/simple_type.rb +0 -247
- /data/lib/lutaml/model/{hash → hash_adapter}/document.rb +0 -0
- /data/lib/lutaml/model/{hash → hash_adapter}/mapping.rb +0 -0
- /data/lib/lutaml/model/{hash → hash_adapter}/mapping_rule.rb +0 -0
- /data/lib/lutaml/model/{hash → hash_adapter}/standard_adapter.rb +0 -0
- /data/lib/lutaml/model/{hash → hash_adapter}/transform.rb +0 -0
@@ -0,0 +1,194 @@
|
|
1
|
+
module Lutaml
|
2
|
+
module Model
|
3
|
+
class Collection < Lutaml::Model::Serializable
|
4
|
+
include Enumerable
|
5
|
+
|
6
|
+
class << self
|
7
|
+
attr_reader :instance_type,
|
8
|
+
:instance_name,
|
9
|
+
:order_by_field,
|
10
|
+
:order_direction
|
11
|
+
|
12
|
+
def instances(name, type, &block)
|
13
|
+
attribute(name, type, collection: true, validations: block)
|
14
|
+
|
15
|
+
@instance_type = Lutaml::Model::Attribute.cast_type!(type)
|
16
|
+
@instance_name = name
|
17
|
+
|
18
|
+
define_method(:"#{name}=") do |collection|
|
19
|
+
self.collection = collection
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def ordered(by:, order: :asc)
|
24
|
+
@order_by_field = by.to_sym
|
25
|
+
@order_direction = order
|
26
|
+
end
|
27
|
+
|
28
|
+
def sort_configured?
|
29
|
+
!!@order_by_field
|
30
|
+
end
|
31
|
+
|
32
|
+
def to(format, instance, options = {})
|
33
|
+
mappings = mappings_for(format)
|
34
|
+
|
35
|
+
if mappings.no_root? && format == :xml
|
36
|
+
mappings.mappings.map do |mapping|
|
37
|
+
serialize_for_mapping(mapping, instance, format, options)
|
38
|
+
end.join("\n")
|
39
|
+
else
|
40
|
+
super(format, instance, options.merge(collection: true))
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def serialize_for_mapping(mapping, instance, format, options)
|
45
|
+
options[:tag_name] = mapping.name
|
46
|
+
|
47
|
+
attr_value = instance.public_send(mapping.to)
|
48
|
+
return if attr_value.nil? || attr_value.empty?
|
49
|
+
|
50
|
+
attr_value = [attr_value] unless attr_value.is_a?(Array)
|
51
|
+
attr_value.map { |v| v.public_send(:"to_#{format}", options) }
|
52
|
+
end
|
53
|
+
|
54
|
+
def as(format, instance, options = {})
|
55
|
+
mappings = mappings_for(format)
|
56
|
+
data = super
|
57
|
+
|
58
|
+
if mappings.no_root? && format != :xml && !mappings.root_mapping
|
59
|
+
Utils.fetch_str_or_sym(data, instance_name)
|
60
|
+
else
|
61
|
+
data
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def from(format, data, options = {})
|
66
|
+
mappings = mappings_for(format)
|
67
|
+
if mappings.no_root? && format == :xml
|
68
|
+
tag_name = mappings.find_by_to(instance_name).name
|
69
|
+
data = "<#{tag_name}>#{data}</#{tag_name}>"
|
70
|
+
end
|
71
|
+
|
72
|
+
super(format, data, options.merge(from_collection: true))
|
73
|
+
end
|
74
|
+
|
75
|
+
def of(format, data, options = {})
|
76
|
+
mappings = mappings_for(format)
|
77
|
+
|
78
|
+
if mappings.no_root? && format != :xml && !mappings.root_mapping
|
79
|
+
data = { mappings.find_by_to(instance_name).name => data }
|
80
|
+
end
|
81
|
+
|
82
|
+
super(format, data, options.merge(from_collection: true))
|
83
|
+
end
|
84
|
+
|
85
|
+
def apply_mappings(data, format, options = {})
|
86
|
+
super(data, format, options.merge(collection: true))
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
attr_reader :register
|
91
|
+
|
92
|
+
def initialize(items = [], register: Lutaml::Model::Config.default_register)
|
93
|
+
super()
|
94
|
+
|
95
|
+
@register = register
|
96
|
+
items = [items].compact unless items.is_a?(Array)
|
97
|
+
|
98
|
+
register_object = Lutaml::Model::GlobalRegister.lookup(register)
|
99
|
+
type = register_object.get_class_without_register(self.class.instance_type)
|
100
|
+
self.collection = items.map do |item|
|
101
|
+
if item.is_a?(type)
|
102
|
+
item
|
103
|
+
elsif type <= Lutaml::Model::Type::Value
|
104
|
+
type.cast(item)
|
105
|
+
else
|
106
|
+
type.new(item, register: register)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
sort_items!
|
111
|
+
end
|
112
|
+
|
113
|
+
def to_format(format, options = {})
|
114
|
+
super(format, options.merge(collection: true))
|
115
|
+
end
|
116
|
+
|
117
|
+
def collection
|
118
|
+
instance_variable_get(:"@#{self.class.instance_name}")
|
119
|
+
end
|
120
|
+
|
121
|
+
def collection=(collection)
|
122
|
+
instance_variable_set(:"@#{self.class.instance_name}", collection)
|
123
|
+
sort_items!
|
124
|
+
end
|
125
|
+
|
126
|
+
def union(other)
|
127
|
+
self.class.new((items + other.items).uniq)
|
128
|
+
end
|
129
|
+
|
130
|
+
def intersection(other)
|
131
|
+
self.class.new(items & other.items)
|
132
|
+
end
|
133
|
+
|
134
|
+
def difference(other)
|
135
|
+
self.class.new(items - other.items)
|
136
|
+
end
|
137
|
+
|
138
|
+
def each(&block)
|
139
|
+
collection.each(&block)
|
140
|
+
end
|
141
|
+
|
142
|
+
def size
|
143
|
+
collection.size
|
144
|
+
end
|
145
|
+
|
146
|
+
def first
|
147
|
+
collection.first
|
148
|
+
end
|
149
|
+
|
150
|
+
def last
|
151
|
+
collection.last
|
152
|
+
end
|
153
|
+
|
154
|
+
def <<(item)
|
155
|
+
push(item)
|
156
|
+
end
|
157
|
+
|
158
|
+
def push(item)
|
159
|
+
collection.push(item)
|
160
|
+
sort_items!
|
161
|
+
end
|
162
|
+
|
163
|
+
def [](index)
|
164
|
+
collection[index]
|
165
|
+
end
|
166
|
+
|
167
|
+
def []=(index, value)
|
168
|
+
collection[index] = value
|
169
|
+
sort_items!
|
170
|
+
end
|
171
|
+
|
172
|
+
def empty?
|
173
|
+
collection&.empty?
|
174
|
+
end
|
175
|
+
|
176
|
+
def order_defined?
|
177
|
+
self.class.sort_configured?
|
178
|
+
end
|
179
|
+
|
180
|
+
def sort_items!
|
181
|
+
return if collection.nil?
|
182
|
+
return unless order_defined?
|
183
|
+
|
184
|
+
unless collection&.one?
|
185
|
+
field = self.class.order_by_field
|
186
|
+
direction = self.class.order_direction
|
187
|
+
|
188
|
+
collection.sort_by! { |item| item.send(field) }
|
189
|
+
collection.reverse! if direction == :desc
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
@@ -467,7 +467,7 @@ module Lutaml
|
|
467
467
|
return format_single_value(
|
468
468
|
value1,
|
469
469
|
parent_node,
|
470
|
-
"#{label}#{
|
470
|
+
"#{label}#{" (#{type_info})" if type_info}",
|
471
471
|
)
|
472
472
|
end
|
473
473
|
|
@@ -482,7 +482,7 @@ module Lutaml
|
|
482
482
|
when ComparableModel
|
483
483
|
format_object_attributes(value1, value2, parent_node)
|
484
484
|
else
|
485
|
-
node = Tree.new("#{label}#{
|
485
|
+
node = Tree.new("#{label}#{" (#{type_info})" if type_info}:")
|
486
486
|
parent_node.add_child(node)
|
487
487
|
node.add_child(Tree.new("- #{format_value(value1)}", color: :red))
|
488
488
|
node.add_child(Tree.new("+ #{format_value(value2)}", color: :green))
|
@@ -495,7 +495,7 @@ module Lutaml
|
|
495
495
|
# @param label [String] The label for the value
|
496
496
|
# @return [String] Formatted single value
|
497
497
|
def format_single_value(value, parent_node, label, color = nil)
|
498
|
-
node = Tree.new("#{label}#{label.empty?
|
498
|
+
node = Tree.new("#{label}#{':' unless label.empty?}", color: color)
|
499
499
|
parent_node.add_child(node)
|
500
500
|
|
501
501
|
case value
|
data/lib/lutaml/model/config.rb
CHANGED
@@ -3,11 +3,13 @@ module Lutaml
|
|
3
3
|
module Config
|
4
4
|
extend self
|
5
5
|
|
6
|
-
AVAILABLE_FORMATS = %i[xml json yaml toml hash].freeze
|
6
|
+
AVAILABLE_FORMATS = %i[xml json jsonl yaml toml hash].freeze
|
7
7
|
KEY_VALUE_FORMATS = AVAILABLE_FORMATS - %i[xml]
|
8
8
|
|
9
9
|
def configure
|
10
10
|
yield self
|
11
|
+
|
12
|
+
self
|
11
13
|
end
|
12
14
|
|
13
15
|
# This will generate the following methods
|
@@ -55,11 +57,12 @@ module Lutaml
|
|
55
57
|
end
|
56
58
|
|
57
59
|
def adapter_for(format)
|
58
|
-
|
60
|
+
@adapters[format]
|
59
61
|
end
|
60
62
|
|
61
63
|
def set_adapter_for(format, adapter)
|
62
|
-
|
64
|
+
@adapters ||= {}
|
65
|
+
@adapters[format] = adapter
|
63
66
|
end
|
64
67
|
|
65
68
|
def mappings_class_for(format)
|
@@ -71,10 +74,27 @@ module Lutaml
|
|
71
74
|
end
|
72
75
|
|
73
76
|
def class_for(adapter, type)
|
77
|
+
# TODO: Remove once HashAdapter namespace is renamed to Hash
|
78
|
+
adapter = "hash_adapter" if adapter == "hash"
|
79
|
+
|
74
80
|
Lutaml::Model.const_get(to_class_name(adapter))
|
75
81
|
.const_get(to_class_name(type))
|
76
82
|
end
|
77
83
|
|
84
|
+
def default_register
|
85
|
+
@default_register ||= :default
|
86
|
+
end
|
87
|
+
|
88
|
+
def default_register=(value)
|
89
|
+
@default_register = case value
|
90
|
+
when Symbol then value
|
91
|
+
when Lutaml::Model::Register then value.id
|
92
|
+
else
|
93
|
+
raise "Unknown register: #{value}, expected a Symbol or a Lutaml::Model::Register instance"
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
# @api private
|
78
98
|
def to_class_name(str)
|
79
99
|
str.to_s.split("_").map(&:capitalize).join
|
80
100
|
end
|
@@ -86,6 +106,9 @@ module Lutaml
|
|
86
106
|
end
|
87
107
|
|
88
108
|
def load_adapter_file(adapter, type)
|
109
|
+
# TODO: Remove once HashAdapter namespace is renamed to Hash
|
110
|
+
adapter = "hash_adapter" if adapter == "hash"
|
111
|
+
|
89
112
|
adapter_file = File.join(adapter, type)
|
90
113
|
require_relative adapter_file
|
91
114
|
rescue LoadError
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Lutaml
|
2
|
+
module Model
|
3
|
+
class ElementCountOutOfRangeError < Error
|
4
|
+
def initialize(attr_name, appearance_count, range)
|
5
|
+
@attr_name = attr_name
|
6
|
+
@appearance_count = appearance_count
|
7
|
+
@range = range
|
8
|
+
|
9
|
+
super()
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_s
|
13
|
+
"`#{@attr_name}` expected to appear between '#{@range.min}' and '#{@range.max}' time#{times_plural(@range.max)}, but #{times_appeared}."
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def times_appeared
|
19
|
+
return "never appeared" if @appearance_count&.zero?
|
20
|
+
|
21
|
+
"appeared only #{@appearance_count} time#{times_plural(@appearance_count)}"
|
22
|
+
end
|
23
|
+
|
24
|
+
def times_plural(count)
|
25
|
+
"s" if count > 1
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Lutaml
|
2
|
+
module Model
|
3
|
+
class InvalidAttributeOptionsError < Error
|
4
|
+
def initialize(name, invalid_opts)
|
5
|
+
@name = name
|
6
|
+
@invalid_opts = invalid_opts
|
7
|
+
|
8
|
+
super()
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_s
|
12
|
+
"Invalid options given for `#{@name}` #{@invalid_opts}"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -9,11 +9,9 @@ module Lutaml
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def to_s
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
"Choice upper bound `#{@max}` must be positive"
|
16
|
-
end
|
12
|
+
bound_name, value = @min.negative? ? ["lower", @min] : ["upper", @max]
|
13
|
+
|
14
|
+
"Choice #{bound_name} bound `#{value}` must be positive"
|
17
15
|
end
|
18
16
|
end
|
19
17
|
end
|
@@ -4,14 +4,16 @@ module Lutaml
|
|
4
4
|
module Model
|
5
5
|
module Type
|
6
6
|
class InvalidValueError < Error
|
7
|
-
def initialize(
|
8
|
-
@
|
7
|
+
def initialize(value, allowed_values)
|
8
|
+
@value = value
|
9
|
+
@allowed_values = allowed_values
|
9
10
|
|
10
11
|
super()
|
11
12
|
end
|
12
13
|
|
13
14
|
def to_s
|
14
|
-
@
|
15
|
+
"`#{@value}` is invalid, must be one of the " \
|
16
|
+
"following #{@allowed_values.inspect}"
|
15
17
|
end
|
16
18
|
end
|
17
19
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Lutaml
|
4
|
+
module Model
|
5
|
+
module Type
|
6
|
+
class MaxBoundError < Error
|
7
|
+
def initialize(value, max_bound)
|
8
|
+
@value = value
|
9
|
+
@max_bound = max_bound
|
10
|
+
|
11
|
+
super()
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_s
|
15
|
+
"Value #{@value} is greater than the set maximum limit #{@max_bound}"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Lutaml
|
4
|
+
module Model
|
5
|
+
module Type
|
6
|
+
class MaxLengthError < Error
|
7
|
+
def initialize(value, max_length)
|
8
|
+
@value = value
|
9
|
+
@max_length = max_length
|
10
|
+
|
11
|
+
super()
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_s
|
15
|
+
"String \"#{@value}\" length (#{@value.length}) is greater than the maximum allowed length #{@max_length}"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Lutaml
|
4
|
+
module Model
|
5
|
+
module Type
|
6
|
+
class MinBoundError < Error
|
7
|
+
def initialize(value, min_bound)
|
8
|
+
@value = value
|
9
|
+
@min_bound = min_bound
|
10
|
+
|
11
|
+
super()
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_s
|
15
|
+
"Value #{@value} is less than the set minimum limit #{@min_bound}"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Lutaml
|
4
|
+
module Model
|
5
|
+
module Type
|
6
|
+
class MinLengthError < Error
|
7
|
+
def initialize(value, min_length)
|
8
|
+
@value = value
|
9
|
+
@min_length = min_length
|
10
|
+
|
11
|
+
super()
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_s
|
15
|
+
"String \"#{@value}\" length (#{@value.length}) is less than the minimum required length #{@min_length}"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Lutaml
|
2
|
+
module Model
|
3
|
+
module Type
|
4
|
+
class PatternNotMatchedError < Error
|
5
|
+
def initialize(value, pattern)
|
6
|
+
@pattern = pattern
|
7
|
+
@value = value
|
8
|
+
|
9
|
+
super()
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_s
|
13
|
+
"\"#{@value}\" does not match #{@pattern.inspect}"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/lutaml/model/error.rb
CHANGED
@@ -11,6 +11,7 @@ require_relative "error/incorrect_mapping_argument_error"
|
|
11
11
|
require_relative "error/pattern_not_matched_error"
|
12
12
|
require_relative "error/unknown_adapter_type_error"
|
13
13
|
require_relative "error/collection_count_out_of_range_error"
|
14
|
+
require_relative "error/element_count_out_of_range_error"
|
14
15
|
require_relative "error/validation_error"
|
15
16
|
require_relative "error/type_not_enabled_error"
|
16
17
|
require_relative "error/type_error"
|
@@ -18,6 +19,11 @@ require_relative "error/unknown_type_error"
|
|
18
19
|
require_relative "error/multiple_mappings_error"
|
19
20
|
require_relative "error/collection_true_missing_error"
|
20
21
|
require_relative "error/type/invalid_value_error"
|
22
|
+
require_relative "error/type/min_bound_error"
|
23
|
+
require_relative "error/type/max_bound_error"
|
24
|
+
require_relative "error/type/pattern_not_matched_error"
|
25
|
+
require_relative "error/type/min_length_error"
|
26
|
+
require_relative "error/type/max_length_error"
|
21
27
|
require_relative "error/incorrect_sequence_error"
|
22
28
|
require_relative "error/choice_upper_bound_error"
|
23
29
|
require_relative "error/no_root_mapping_error"
|
@@ -27,3 +33,7 @@ require_relative "error/unknown_sequence_mapping_error"
|
|
27
33
|
require_relative "error/choice_lower_bound_error"
|
28
34
|
require_relative "error/no_root_namespace_error"
|
29
35
|
require_relative "error/polymorphic_error"
|
36
|
+
require_relative "error/validation_failed_error"
|
37
|
+
require_relative "error/invalid_attribute_name_error"
|
38
|
+
require_relative "error/invalid_attribute_options_error"
|
39
|
+
require_relative "error/register/not_registrable_class_error"
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Lutaml
|
2
|
+
module Model
|
3
|
+
class Errors
|
4
|
+
include Enumerable
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@errors = {}
|
8
|
+
end
|
9
|
+
|
10
|
+
def add(attr, error)
|
11
|
+
@errors[attr] ||= []
|
12
|
+
@errors[attr] << error
|
13
|
+
end
|
14
|
+
|
15
|
+
def empty?
|
16
|
+
@errors.empty?
|
17
|
+
end
|
18
|
+
|
19
|
+
def each(&block)
|
20
|
+
@errors.each(&block)
|
21
|
+
end
|
22
|
+
|
23
|
+
def full_messages
|
24
|
+
@errors.map { |attr, errors| "#{attr}: #{errors.join(', ')}" }
|
25
|
+
end
|
26
|
+
|
27
|
+
def messages
|
28
|
+
@errors.map { |_, errors| errors.join(", ") }.flatten
|
29
|
+
end
|
30
|
+
|
31
|
+
def to_s
|
32
|
+
full_messages.join("\n")
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -15,12 +15,15 @@ module Lutaml
|
|
15
15
|
::Lutaml::Model::Serialize.register_from_format_method(format)
|
16
16
|
::Lutaml::Model::Serialize.register_to_format_method(format)
|
17
17
|
|
18
|
+
Lutaml::Model::Config.set_adapter_for(format, adapter_class)
|
19
|
+
|
18
20
|
Lutaml::Model::Config.define_singleton_method(:"#{format}_adapter") do
|
19
|
-
|
21
|
+
@adapters[format] || adapter_class
|
20
22
|
end
|
21
23
|
|
22
24
|
Lutaml::Model::Config.define_singleton_method(:"#{format}_adapter=") do |adapter_klass|
|
23
|
-
|
25
|
+
@adapters ||= {}
|
26
|
+
@adapters[format] = adapter_klass
|
24
27
|
end
|
25
28
|
end
|
26
29
|
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Lutaml
|
4
|
+
module Model
|
5
|
+
class GlobalRegister
|
6
|
+
include Singleton
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@registers = {}
|
10
|
+
default_register = Lutaml::Model::Register.new(:default)
|
11
|
+
register(default_register)
|
12
|
+
end
|
13
|
+
|
14
|
+
def register(model_register)
|
15
|
+
@registers[model_register.id] = model_register
|
16
|
+
end
|
17
|
+
|
18
|
+
def lookup(id)
|
19
|
+
@registers[id.to_sym]
|
20
|
+
end
|
21
|
+
|
22
|
+
def remove(id)
|
23
|
+
@registers.delete(id.to_sym)
|
24
|
+
end
|
25
|
+
|
26
|
+
class << self
|
27
|
+
def register(model_register)
|
28
|
+
instance.register(model_register)
|
29
|
+
end
|
30
|
+
|
31
|
+
def lookup(id)
|
32
|
+
instance.lookup(id)
|
33
|
+
end
|
34
|
+
|
35
|
+
def remove(id)
|
36
|
+
instance.remove(id)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -7,11 +7,11 @@ module Lutaml
|
|
7
7
|
end
|
8
8
|
end
|
9
9
|
|
10
|
-
require_relative "
|
11
|
-
require_relative "
|
12
|
-
require_relative "
|
13
|
-
require_relative "
|
14
|
-
require_relative "
|
10
|
+
require_relative "hash_adapter/standard_adapter"
|
11
|
+
require_relative "hash_adapter/document"
|
12
|
+
require_relative "hash_adapter/mapping"
|
13
|
+
require_relative "hash_adapter/mapping_rule"
|
14
|
+
require_relative "hash_adapter/transform"
|
15
15
|
|
16
16
|
Lutaml::Model::FormatRegistry.register(
|
17
17
|
:hash,
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Lutaml
|
4
|
+
module Model
|
5
|
+
module Jsonl
|
6
|
+
class Document
|
7
|
+
def initialize(jsons = [], register: nil)
|
8
|
+
@jsons = jsons
|
9
|
+
@register = register || Lutaml::Model::Config.default_register
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|