lutaml-model 0.8.18 → 0.8.22
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/.github/workflows/dependent-tests.yml +1 -1
- data/.github/workflows/rake.yml +1 -0
- data/.rubocop.yml +1 -1
- data/.rubocop_todo.yml +133 -72
- data/bench/bench_common.rb +8 -5
- data/bench/bench_niso.rb +1 -2
- data/bench/gate_config.rb +4 -1
- data/benchmark/serialization_benchmark.rb +4 -4
- data/docs/_guides/builder-dsl.adoc +127 -0
- data/docs/_guides/value-transformations.adoc +27 -0
- data/lib/compat/opal/generate_boot.rb +3 -1
- data/lib/compat/opal/lutaml_model_boot.rb +10 -7
- data/lib/compat/opal/moxml_boot.rb +6 -1
- data/lib/lutaml/hash_format/format.rb +29 -0
- data/lib/lutaml/hash_format.rb +5 -27
- data/lib/lutaml/json/format.rb +61 -0
- data/lib/lutaml/json.rb +4 -59
- data/lib/lutaml/jsonl/format.rb +22 -0
- data/lib/lutaml/jsonl.rb +5 -19
- data/lib/lutaml/key_value/format.rb +26 -0
- data/lib/lutaml/key_value/transform.rb +4 -1
- data/lib/lutaml/key_value/transformation/value_serializer.rb +0 -2
- data/lib/lutaml/key_value.rb +4 -21
- data/lib/lutaml/model/attribute.rb +38 -4
- data/lib/lutaml/model/collection.rb +2 -2
- data/lib/lutaml/model/compiled_rule.rb +1 -1
- data/lib/lutaml/model/config.rb +2 -2
- data/lib/lutaml/model/consolidation_map.rb +2 -2
- data/lib/lutaml/model/consolidation_rule/dispatch_block.rb +2 -2
- data/lib/lutaml/model/errors.rb +2 -2
- data/lib/lutaml/model/global_context.rb +4 -2
- data/lib/lutaml/model/mapping/mapping_rule.rb +4 -1
- data/lib/lutaml/model/mapping/model_mapping.rb +2 -2
- data/lib/lutaml/model/runtime_compatibility.rb +2 -2
- data/lib/lutaml/model/schema/class_loader.rb +2 -1
- data/lib/lutaml/model/schema/decorators/definition_collection.rb +4 -4
- data/lib/lutaml/model/schema/definitions/namespace.rb +2 -1
- data/lib/lutaml/model/schema/file_writer.rb +5 -2
- data/lib/lutaml/model/schema/renderers/base.rb +4 -3
- data/lib/lutaml/model/schema/renderers/mappings.rb +9 -3
- data/lib/lutaml/model/schema/renderers/member_decls.rb +9 -3
- data/lib/lutaml/model/schema/renderers/model.rb +18 -6
- data/lib/lutaml/model/schema/renderers/required_files_calculator.rb +2 -1
- data/lib/lutaml/model/schema/renderers.rb +2 -1
- data/lib/lutaml/model/schema/rnc_compiler/source_resolver.rb +6 -2
- data/lib/lutaml/model/schema/rnc_compiler.rb +3 -1
- data/lib/lutaml/model/schema/rng_compiler/element_visitor.rb +35 -15
- data/lib/lutaml/model/schema/rng_compiler/value_type_resolver.rb +4 -2
- data/lib/lutaml/model/schema/rng_compiler.rb +10 -5
- data/lib/lutaml/model/schema/xml_compiler/element_order.rb +2 -1
- data/lib/lutaml/model/schema/xml_compiler/spec_builder/complex_types.rb +4 -2
- data/lib/lutaml/model/schema/xml_compiler/spec_builder/members.rb +39 -13
- data/lib/lutaml/model/schema/xml_compiler/spec_builder.rb +29 -10
- data/lib/lutaml/model/schema/xml_compiler/supported_data_types.rb +2 -2
- data/lib/lutaml/model/schema/xml_compiler.rb +10 -5
- data/lib/lutaml/model/sequence.rb +4 -4
- data/lib/lutaml/model/serialize/attribute_definition.rb +10 -9
- data/lib/lutaml/model/serialize/builder.rb +55 -0
- data/lib/lutaml/model/serialize/format_conversion.rb +2 -2
- data/lib/lutaml/model/serialize/initialization.rb +12 -3
- data/lib/lutaml/model/serialize/model_import.rb +1 -0
- data/lib/lutaml/model/serialize.rb +4 -3
- data/lib/lutaml/model/type/uninitialized_class_guard.rb +1 -1
- data/lib/lutaml/model/type.rb +9 -0
- data/lib/lutaml/model/type_registry.rb +2 -2
- data/lib/lutaml/model/uninitialized_class.rb +1 -1
- data/lib/lutaml/model/union.rb +5 -2
- data/lib/lutaml/model/utils.rb +2 -2
- data/lib/lutaml/model/value_policy.rb +27 -0
- data/lib/lutaml/model/version.rb +1 -1
- data/lib/lutaml/model.rb +17 -16
- data/lib/lutaml/rdf/mapping.rb +2 -2
- data/lib/lutaml/rdf/namespace_set.rb +2 -2
- data/lib/lutaml/rdf/transform.rb +2 -2
- data/lib/lutaml/toml/format.rb +48 -0
- data/lib/lutaml/toml.rb +5 -46
- data/lib/lutaml/xml/adapter/base_adapter.rb +2 -2
- data/lib/lutaml/xml/builder/base.rb +2 -2
- data/lib/lutaml/xml/format.rb +331 -0
- data/lib/lutaml/xml/mapping.rb +2 -2
- data/lib/lutaml/xml/mapping_rule.rb +62 -3
- data/lib/lutaml/xml/model_transform.rb +132 -55
- data/lib/lutaml/xml/namespace_collector.rb +3 -3
- data/lib/lutaml/xml/parse_session.rb +59 -0
- data/lib/lutaml/xml/parsed_namespace_set.rb +2 -2
- data/lib/lutaml/xml/schema/builder.rb +5 -5
- data/lib/lutaml/xml/schema/xsd/schema_location_mapping.rb +2 -2
- data/lib/lutaml/xml/schema/xsd.rb +0 -2
- data/lib/lutaml/xml/schema/xsd_schema.rb +2 -1
- data/lib/lutaml/xml/serialization/format_conversion.rb +3 -3
- data/lib/lutaml/xml/transformation/element_builder.rb +2 -1
- data/lib/lutaml/xml/transformation/ordered_applier.rb +99 -4
- data/lib/lutaml/xml/xml_element.rb +2 -0
- data/lib/lutaml/xml.rb +4 -328
- data/lib/lutaml/yaml/format.rb +30 -0
- data/lib/lutaml/yaml.rb +5 -28
- data/lib/lutaml/yamls/adapter/mapping.rb +2 -2
- data/lib/lutaml/yamls/format.rb +22 -0
- data/lib/lutaml/yamls.rb +5 -19
- data/lib/tasks/benchmark_runner.rb +2 -2
- data/lutaml-model.gemspec +1 -1
- data/spec/lutaml/model/attribute_apply_value_map_spec.rb +26 -13
- data/spec/lutaml/model/attribute_spec.rb +8 -3
- data/spec/lutaml/model/custom_bibtex_adapter_spec.rb +2 -2
- data/spec/lutaml/model/custom_from_empty_values_spec.rb +74 -0
- data/spec/lutaml/model/custom_vobject_adapter_spec.rb +8 -8
- data/spec/lutaml/model/defaults_spec.rb +45 -0
- data/spec/lutaml/model/json_spec.rb +1 -2
- data/spec/lutaml/model/ordered_content_spec.rb +18 -7
- data/spec/lutaml/model/serialize/builder_spec.rb +361 -0
- data/spec/lutaml/model/store_spec.rb +3 -1
- data/spec/lutaml/model/transform_apply_value_map_spec.rb +6 -3
- data/spec/lutaml/model/union_attribute_spec.rb +4 -2
- data/spec/lutaml/model/value_policy_spec.rb +82 -0
- data/spec/lutaml/require_load_order_spec.rb +25 -0
- data/spec/lutaml/xml/attribute_element_namespace_disjoint_spec.rb +88 -0
- data/spec/lutaml/xml/attribute_namespace_disjointness_spec.rb +125 -0
- data/spec/lutaml/xml/out_of_namespace_parsing_spec.rb +123 -0
- data/spec/lutaml/xml/schema/rnc_compiler_spec.rb +17 -6
- data/spec/lutaml/xml/schema/rng_compiler_spec.rb +15 -6
- data/spec/lutaml/xml/w3c_types_spec.rb +3 -6
- metadata +22 -4
|
@@ -38,7 +38,9 @@ DECL_RE = /autoload\s+:[A-Za-z0-9_]+\s*,\s*"([^"]+)"/
|
|
|
38
38
|
# DECL_RE can match. We only merge when the line ends right after the
|
|
39
39
|
# comma that follows `autoload :Name`.
|
|
40
40
|
def join_multiline_autoloads(src)
|
|
41
|
-
src.gsub(/(autoload\s+:[A-Za-z0-9_]+\s*,)\s*\n\s*/)
|
|
41
|
+
src.gsub(/(autoload\s+:[A-Za-z0-9_]+\s*,)\s*\n\s*/) do
|
|
42
|
+
"#{Regexp.last_match(1)} "
|
|
43
|
+
end
|
|
42
44
|
end
|
|
43
45
|
|
|
44
46
|
# Resolve an autoload's raw string argument to a require path relative to
|
|
@@ -21,22 +21,19 @@
|
|
|
21
21
|
|
|
22
22
|
require "lutaml/model"
|
|
23
23
|
require "lutaml/xml"
|
|
24
|
-
require "lutaml/hash_format"
|
|
25
|
-
require "lutaml/json"
|
|
26
|
-
require "lutaml/jsonl"
|
|
27
24
|
require "lutaml/jsonld"
|
|
28
|
-
require "lutaml/key_value"
|
|
29
|
-
require "lutaml/toml"
|
|
30
25
|
require "lutaml/turtle"
|
|
31
|
-
require "lutaml/yaml"
|
|
32
26
|
require "lutaml/yamlld"
|
|
33
|
-
require "lutaml/yamls"
|
|
34
27
|
require "lutaml/hash_format/adapter"
|
|
28
|
+
require "lutaml/hash_format/format"
|
|
29
|
+
require "lutaml/json/format"
|
|
35
30
|
require "lutaml/jsonl/adapter"
|
|
31
|
+
require "lutaml/jsonl/format"
|
|
36
32
|
require "lutaml/jsonld/adapter"
|
|
37
33
|
require "lutaml/key_value/adapter"
|
|
38
34
|
require "lutaml/key_value/data_model"
|
|
39
35
|
require "lutaml/key_value/document"
|
|
36
|
+
require "lutaml/key_value/format"
|
|
40
37
|
require "lutaml/key_value/mapping"
|
|
41
38
|
require "lutaml/key_value/mapping_rule"
|
|
42
39
|
require "lutaml/key_value/transform"
|
|
@@ -103,6 +100,7 @@ require "lutaml/model/uninitialized_class"
|
|
|
103
100
|
require "lutaml/model/union"
|
|
104
101
|
require "lutaml/model/utils"
|
|
105
102
|
require "lutaml/model/validation"
|
|
103
|
+
require "lutaml/model/value_policy"
|
|
106
104
|
require "lutaml/model/value_transformer"
|
|
107
105
|
require "lutaml/model/version"
|
|
108
106
|
require "lutaml/model/yaml"
|
|
@@ -121,6 +119,7 @@ require "lutaml/rdf/namespace_set"
|
|
|
121
119
|
require "lutaml/rdf/namespaces"
|
|
122
120
|
require "lutaml/rdf/term_definition"
|
|
123
121
|
require "lutaml/rdf/transform"
|
|
122
|
+
require "lutaml/toml/format"
|
|
124
123
|
require "lutaml/turtle/adapter"
|
|
125
124
|
require "lutaml/turtle/mapping"
|
|
126
125
|
require "lutaml/turtle/transform"
|
|
@@ -143,6 +142,7 @@ require "lutaml/xml/document"
|
|
|
143
142
|
require "lutaml/xml/element"
|
|
144
143
|
require "lutaml/xml/element_prefix_resolver"
|
|
145
144
|
require "lutaml/xml/encoding_normalizer"
|
|
145
|
+
require "lutaml/xml/format"
|
|
146
146
|
require "lutaml/xml/format_chooser"
|
|
147
147
|
require "lutaml/xml/hoisting_algorithm"
|
|
148
148
|
require "lutaml/xml/listener"
|
|
@@ -164,6 +164,7 @@ require "lutaml/xml/namespace_scope_config"
|
|
|
164
164
|
require "lutaml/xml/namespace_type_resolver"
|
|
165
165
|
require "lutaml/xml/namespace_usage"
|
|
166
166
|
require "lutaml/xml/oga"
|
|
167
|
+
require "lutaml/xml/parse_session"
|
|
167
168
|
require "lutaml/xml/parsed_namespace_declaration"
|
|
168
169
|
require "lutaml/xml/parsed_namespace_set"
|
|
169
170
|
require "lutaml/xml/polymorphic_value_handler"
|
|
@@ -185,9 +186,11 @@ require "lutaml/xml/xml_attribute"
|
|
|
185
186
|
require "lutaml/xml/xml_element"
|
|
186
187
|
require "lutaml/xml/xsd_validator"
|
|
187
188
|
require "lutaml/yaml/adapter"
|
|
189
|
+
require "lutaml/yaml/format"
|
|
188
190
|
require "lutaml/yaml/schema"
|
|
189
191
|
require "lutaml/yamlld/adapter"
|
|
190
192
|
require "lutaml/yamls/adapter"
|
|
193
|
+
require "lutaml/yamls/format"
|
|
191
194
|
require "lutaml/hash_format/adapter/document"
|
|
192
195
|
require "lutaml/hash_format/adapter/mapping"
|
|
193
196
|
require "lutaml/hash_format/adapter/mapping_rule"
|
|
@@ -34,6 +34,10 @@ if RUBY_ENGINE == "opal"
|
|
|
34
34
|
require "moxml/doctype"
|
|
35
35
|
require "moxml/entity_reference"
|
|
36
36
|
require "moxml/entity_registry"
|
|
37
|
+
require "moxml/entity"
|
|
38
|
+
require "moxml/entity/restorer"
|
|
39
|
+
require "moxml/entity/reference"
|
|
40
|
+
require "moxml/xml_emitter"
|
|
37
41
|
require "moxml/adapter"
|
|
38
42
|
require "moxml/adapter/base"
|
|
39
43
|
require "moxml/adapter/customized_rexml"
|
|
@@ -46,10 +50,11 @@ if RUBY_ENGINE == "opal"
|
|
|
46
50
|
require "moxml/sax/namespace_splitter"
|
|
47
51
|
require "moxml/adapter/rexml"
|
|
48
52
|
require "moxml/adapter/customized_oga"
|
|
53
|
+
require "moxml/adapter/customized_oga/entity_decoder"
|
|
54
|
+
require "moxml/adapter/customized_oga/raw_value_override"
|
|
49
55
|
require "moxml/adapter/customized_oga/xml_declaration"
|
|
50
56
|
require "moxml/adapter/customized_oga/xml_generator"
|
|
51
57
|
require "moxml/adapter/oga"
|
|
52
|
-
require "moxml/document_builder"
|
|
53
58
|
require "moxml/builder"
|
|
54
59
|
require "moxml/context"
|
|
55
60
|
require "moxml/config"
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Internal Hash format implementation. Loaded from lib/lutaml/hash_format.rb
|
|
4
|
+
# (the public entrypoint) and from lib/lutaml/model.rb (so the model
|
|
5
|
+
# entrypoint triggers the registration side effects).
|
|
6
|
+
# No require_relative "model" here — keeps the require graph acyclic.
|
|
7
|
+
|
|
8
|
+
module Lutaml
|
|
9
|
+
module HashFormat
|
|
10
|
+
class Error < StandardError; end
|
|
11
|
+
|
|
12
|
+
autoload :Adapter, "#{__dir__}/adapter"
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
Lutaml::Model::FormatRegistry.register(
|
|
17
|
+
:hash,
|
|
18
|
+
mapping_class: Lutaml::HashFormat::Adapter::Mapping,
|
|
19
|
+
adapter_class: Lutaml::HashFormat::Adapter::StandardAdapter,
|
|
20
|
+
transformer: Lutaml::HashFormat::Adapter::Transform,
|
|
21
|
+
key_value: true,
|
|
22
|
+
adapter_options: {
|
|
23
|
+
available: %i[standard standard_hash],
|
|
24
|
+
default: :standard,
|
|
25
|
+
},
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
require_relative "type/serializers"
|
|
29
|
+
Lutaml::HashFormat::Type::Serializers.register_all!
|
data/lib/lutaml/hash_format.rb
CHANGED
|
@@ -1,29 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# Hash format
|
|
4
|
-
#
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class Error < StandardError; end
|
|
9
|
-
|
|
10
|
-
autoload :Adapter, "#{__dir__}/hash_format/adapter"
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
# Register Hash format with the format registry
|
|
15
|
-
Lutaml::Model::FormatRegistry.register(
|
|
16
|
-
:hash,
|
|
17
|
-
mapping_class: Lutaml::HashFormat::Adapter::Mapping,
|
|
18
|
-
adapter_class: Lutaml::HashFormat::Adapter::StandardAdapter,
|
|
19
|
-
transformer: Lutaml::HashFormat::Adapter::Transform,
|
|
20
|
-
key_value: true,
|
|
21
|
-
adapter_options: {
|
|
22
|
-
available: %i[standard standard_hash],
|
|
23
|
-
default: :standard,
|
|
24
|
-
},
|
|
25
|
-
)
|
|
26
|
-
|
|
27
|
-
# Register Hash type serializers
|
|
28
|
-
require_relative "hash_format/type/serializers"
|
|
29
|
-
Lutaml::HashFormat::Type::Serializers.register_all!
|
|
3
|
+
# Public Hash format entrypoint. Loads the base model and the internal
|
|
4
|
+
# implementation. The internal file does not require the model back,
|
|
5
|
+
# which keeps the require graph acyclic.
|
|
6
|
+
require_relative "model"
|
|
7
|
+
require_relative "hash_format/format"
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Internal JSON format implementation. Loaded from lib/lutaml/json.rb
|
|
4
|
+
# (the public entrypoint) and from lib/lutaml/model.rb (so the model
|
|
5
|
+
# entrypoint triggers the registration side effects).
|
|
6
|
+
# No require_relative "model" here — keeps the require graph acyclic.
|
|
7
|
+
|
|
8
|
+
require "lutaml/model/runtime_compatibility"
|
|
9
|
+
require_relative "../key_value/format"
|
|
10
|
+
|
|
11
|
+
module Lutaml
|
|
12
|
+
module Json
|
|
13
|
+
class Error < StandardError; end
|
|
14
|
+
|
|
15
|
+
require_relative "adapter/document"
|
|
16
|
+
require_relative "adapter/mapping"
|
|
17
|
+
require_relative "adapter/mapping_rule"
|
|
18
|
+
require_relative "adapter/transform"
|
|
19
|
+
require_relative "adapter/standard_adapter"
|
|
20
|
+
Lutaml::Model::RuntimeCompatibility.require_native(
|
|
21
|
+
"#{__dir__}/adapter/oj_adapter",
|
|
22
|
+
"#{__dir__}/adapter/multi_json_adapter",
|
|
23
|
+
)
|
|
24
|
+
require_relative "schema"
|
|
25
|
+
|
|
26
|
+
# Convenience aliases for common classes at the module level
|
|
27
|
+
# Allows Lutaml::Json::Mapping to resolve to Lutaml::Json::Adapter::Mapping
|
|
28
|
+
def self.const_missing(name)
|
|
29
|
+
if Adapter.const_defined?(name, false)
|
|
30
|
+
Adapter.const_get(name, false)
|
|
31
|
+
else
|
|
32
|
+
super
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Detect available JSON adapters
|
|
37
|
+
def self.detect_adapter
|
|
38
|
+
return :standard if defined?(::JSON) && Lutaml::Model.opal?
|
|
39
|
+
return :oj if defined?(::Oj)
|
|
40
|
+
return :multi_json if defined?(::MultiJson)
|
|
41
|
+
return :standard if defined?(::JSON)
|
|
42
|
+
|
|
43
|
+
nil
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
Lutaml::Model::FormatRegistry.register(
|
|
49
|
+
:json,
|
|
50
|
+
mapping_class: Lutaml::Json::Adapter::Mapping,
|
|
51
|
+
adapter_class: Lutaml::Json::Adapter::StandardAdapter,
|
|
52
|
+
transformer: Lutaml::Json::Adapter::Transform,
|
|
53
|
+
key_value: true,
|
|
54
|
+
adapter_options: {
|
|
55
|
+
available: %i[standard standard_json multi_json oj],
|
|
56
|
+
default: :standard,
|
|
57
|
+
},
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
require_relative "type/serializers"
|
|
61
|
+
Lutaml::Json::Type::Serializers.register_all!
|
data/lib/lutaml/json.rb
CHANGED
|
@@ -1,62 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# JSON format
|
|
4
|
-
#
|
|
5
|
-
|
|
6
|
-
require "lutaml/model/runtime_compatibility"
|
|
3
|
+
# Public JSON format entrypoint. Loads the base model and the internal
|
|
4
|
+
# implementation. The internal file does not require the model back,
|
|
5
|
+
# which keeps the require graph acyclic.
|
|
7
6
|
require_relative "model"
|
|
8
|
-
require_relative "
|
|
9
|
-
|
|
10
|
-
module Lutaml
|
|
11
|
-
module Json
|
|
12
|
-
class Error < StandardError; end
|
|
13
|
-
|
|
14
|
-
require_relative "json/adapter/document"
|
|
15
|
-
require_relative "json/adapter/mapping"
|
|
16
|
-
require_relative "json/adapter/mapping_rule"
|
|
17
|
-
require_relative "json/adapter/transform"
|
|
18
|
-
require_relative "json/adapter/standard_adapter"
|
|
19
|
-
Lutaml::Model::RuntimeCompatibility.require_native(
|
|
20
|
-
"#{__dir__}/json/adapter/oj_adapter",
|
|
21
|
-
"#{__dir__}/json/adapter/multi_json_adapter",
|
|
22
|
-
)
|
|
23
|
-
require_relative "json/schema"
|
|
24
|
-
|
|
25
|
-
# Convenience aliases for common classes at the module level
|
|
26
|
-
# Allows Lutaml::Json::Mapping to resolve to Lutaml::Json::Adapter::Mapping
|
|
27
|
-
def self.const_missing(name)
|
|
28
|
-
if Adapter.const_defined?(name, false)
|
|
29
|
-
Adapter.const_get(name, false)
|
|
30
|
-
else
|
|
31
|
-
super
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
# Detect available JSON adapters
|
|
36
|
-
def self.detect_adapter
|
|
37
|
-
return :standard if defined?(::JSON) && Lutaml::Model.opal?
|
|
38
|
-
return :oj if defined?(::Oj)
|
|
39
|
-
return :multi_json if defined?(::MultiJson)
|
|
40
|
-
return :standard if defined?(::JSON)
|
|
41
|
-
|
|
42
|
-
nil
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
# Register JSON format with the format registry
|
|
48
|
-
Lutaml::Model::FormatRegistry.register(
|
|
49
|
-
:json,
|
|
50
|
-
mapping_class: Lutaml::Json::Adapter::Mapping,
|
|
51
|
-
adapter_class: Lutaml::Json::Adapter::StandardAdapter,
|
|
52
|
-
transformer: Lutaml::Json::Adapter::Transform,
|
|
53
|
-
key_value: true,
|
|
54
|
-
adapter_options: {
|
|
55
|
-
available: %i[standard standard_json multi_json oj],
|
|
56
|
-
default: :standard,
|
|
57
|
-
},
|
|
58
|
-
)
|
|
59
|
-
|
|
60
|
-
# Register JSON type serializers
|
|
61
|
-
require_relative "json/type/serializers"
|
|
62
|
-
Lutaml::Json::Type::Serializers.register_all!
|
|
7
|
+
require_relative "json/format"
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Internal JSONL format implementation. Loaded from lib/lutaml/jsonl.rb
|
|
4
|
+
# (the public entrypoint) and from lib/lutaml/model.rb (so the model
|
|
5
|
+
# entrypoint triggers the registration side effects).
|
|
6
|
+
# No require_relative "model" here — keeps the require graph acyclic.
|
|
7
|
+
|
|
8
|
+
module Lutaml
|
|
9
|
+
module Jsonl
|
|
10
|
+
class Error < StandardError; end
|
|
11
|
+
|
|
12
|
+
autoload :Adapter, "#{__dir__}/adapter"
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
Lutaml::Model::FormatRegistry.register(
|
|
17
|
+
:jsonl,
|
|
18
|
+
mapping_class: Lutaml::Jsonl::Adapter::Mapping,
|
|
19
|
+
adapter_class: Lutaml::Jsonl::Adapter::StandardAdapter,
|
|
20
|
+
transformer: Lutaml::Jsonl::Adapter::Transform,
|
|
21
|
+
key_value: true,
|
|
22
|
+
)
|
data/lib/lutaml/jsonl.rb
CHANGED
|
@@ -1,21 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# JSONL format
|
|
4
|
-
#
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class Error < StandardError; end
|
|
9
|
-
|
|
10
|
-
autoload :Adapter, "#{__dir__}/jsonl/adapter"
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
# Register JSONL format with the format registry
|
|
15
|
-
Lutaml::Model::FormatRegistry.register(
|
|
16
|
-
:jsonl,
|
|
17
|
-
mapping_class: Lutaml::Jsonl::Adapter::Mapping,
|
|
18
|
-
adapter_class: Lutaml::Jsonl::Adapter::StandardAdapter,
|
|
19
|
-
transformer: Lutaml::Jsonl::Adapter::Transform,
|
|
20
|
-
key_value: true,
|
|
21
|
-
)
|
|
3
|
+
# Public JSONL format entrypoint. Loads the base model and the internal
|
|
4
|
+
# implementation. The internal file does not require the model back,
|
|
5
|
+
# which keeps the require graph acyclic.
|
|
6
|
+
require_relative "model"
|
|
7
|
+
require_relative "jsonl/format"
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Internal KeyValue implementation. Loaded from lib/lutaml/key_value.rb
|
|
4
|
+
# (the public entrypoint) and from lib/lutaml/model.rb (so the model
|
|
5
|
+
# entrypoint triggers the registration side effects).
|
|
6
|
+
# No require_relative "model" here — keeps the require graph acyclic.
|
|
7
|
+
|
|
8
|
+
module Lutaml
|
|
9
|
+
module KeyValue
|
|
10
|
+
autoload :DataModel, "#{__dir__}/data_model"
|
|
11
|
+
autoload :Document, "#{__dir__}/document"
|
|
12
|
+
autoload :Mapping, "#{__dir__}/mapping"
|
|
13
|
+
autoload :MappingRule, "#{__dir__}/mapping_rule"
|
|
14
|
+
autoload :Transform, "#{__dir__}/transform"
|
|
15
|
+
autoload :Transformation, "#{__dir__}/transformation"
|
|
16
|
+
autoload :TransformationBuilder, "#{__dir__}/transformation_builder"
|
|
17
|
+
autoload :Adapter, "#{__dir__}/adapter"
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Register KeyValue transformation builders for all key-value formats
|
|
22
|
+
%i[json yaml toml hash].each do |format|
|
|
23
|
+
Lutaml::Model::TransformationRegistry.register_builder(
|
|
24
|
+
format, Lutaml::KeyValue::TransformationBuilder
|
|
25
|
+
)
|
|
26
|
+
end
|
|
@@ -249,7 +249,10 @@ format)
|
|
|
249
249
|
value = apply_value_map(value, rule.value_map(:from, options), attr)
|
|
250
250
|
|
|
251
251
|
if rule.has_custom_method_for_deserialization?
|
|
252
|
-
|
|
252
|
+
# An empty value ("", [], {}) is a present value per the
|
|
253
|
+
# missing-values semantics and must reach the custom method;
|
|
254
|
+
# only nil (non-existent) skips it (lutaml-model#746).
|
|
255
|
+
return if value.nil?
|
|
253
256
|
|
|
254
257
|
return rule.deserialize(instance, value, attributes, model_class)
|
|
255
258
|
end
|
|
@@ -88,11 +88,9 @@ model_class: nil)
|
|
|
88
88
|
# @param rule [CompiledRule] The compiled rule
|
|
89
89
|
# @return [Boolean] true if the rule defines a nested model
|
|
90
90
|
def nested_model?(rule)
|
|
91
|
-
# rubocop:disable Style/IncludeOrExtend
|
|
92
91
|
# Use include? instead of < because < returns nil (not false) for non-subclasses
|
|
93
92
|
rule.attribute_type.is_a?(Class) &&
|
|
94
93
|
rule.attribute_type.include?(Lutaml::Model::Serialize)
|
|
95
|
-
# rubocop:enable Style/IncludeOrExtend
|
|
96
94
|
end
|
|
97
95
|
|
|
98
96
|
# Serialize a nested model to a hash representation.
|
data/lib/lutaml/key_value.rb
CHANGED
|
@@ -1,24 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
autoload :Document, "#{__dir__}/key_value/document"
|
|
7
|
-
autoload :Mapping, "#{__dir__}/key_value/mapping"
|
|
8
|
-
autoload :MappingRule, "#{__dir__}/key_value/mapping_rule"
|
|
9
|
-
autoload :Transform, "#{__dir__}/key_value/transform"
|
|
10
|
-
autoload :Transformation, "#{__dir__}/key_value/transformation"
|
|
11
|
-
autoload :TransformationBuilder,
|
|
12
|
-
"#{__dir__}/key_value/transformation_builder"
|
|
13
|
-
autoload :Adapter, "#{__dir__}/key_value/adapter"
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
|
|
3
|
+
# Public KeyValue entrypoint. Loads the base model and the internal
|
|
4
|
+
# implementation. The internal file does not require the model back,
|
|
5
|
+
# which keeps the require graph acyclic.
|
|
17
6
|
require_relative "model"
|
|
18
|
-
|
|
19
|
-
# Register KeyValue transformation builders for all key-value formats
|
|
20
|
-
%i[json yaml toml hash].each do |format|
|
|
21
|
-
Lutaml::Model::TransformationRegistry.register_builder(
|
|
22
|
-
format, Lutaml::KeyValue::TransformationBuilder
|
|
23
|
-
)
|
|
24
|
-
end
|
|
7
|
+
require_relative "key_value/format"
|
|
@@ -119,6 +119,17 @@ module Lutaml
|
|
|
119
119
|
@resolver ||= GlobalContext.resolver
|
|
120
120
|
end
|
|
121
121
|
|
|
122
|
+
# The value-shaping policy for this attribute. Constructed lazily so
|
|
123
|
+
# the collection/union/ref flags are settled; memoized because they
|
|
124
|
+
# are fixed after definition.
|
|
125
|
+
def value_policy
|
|
126
|
+
@value_policy ||= ValuePolicy.new(
|
|
127
|
+
collection: collection?,
|
|
128
|
+
union: union?,
|
|
129
|
+
reference: !@options[:ref_model_class].nil?,
|
|
130
|
+
)
|
|
131
|
+
end
|
|
132
|
+
|
|
122
133
|
def type(context_or_register = nil)
|
|
123
134
|
return if unresolved_type.nil?
|
|
124
135
|
|
|
@@ -394,7 +405,9 @@ instance_object = nil)
|
|
|
394
405
|
instance_object)
|
|
395
406
|
elsif options[:default].is_a?(Proc)
|
|
396
407
|
if instance_object
|
|
397
|
-
|
|
408
|
+
::Lutaml::Model::Attribute.evaluating_default do
|
|
409
|
+
instance_object.instance_exec(&options[:default])
|
|
410
|
+
end
|
|
398
411
|
else
|
|
399
412
|
options[:default].call
|
|
400
413
|
end
|
|
@@ -405,6 +418,22 @@ instance_object = nil)
|
|
|
405
418
|
end
|
|
406
419
|
end
|
|
407
420
|
|
|
421
|
+
# Marks the dynamic extent in which a default proc runs against a
|
|
422
|
+
# model instance, so Serialize#method_missing can fall back to the
|
|
423
|
+
# model class for methods the instance does not define (0.7.x
|
|
424
|
+
# compatibility, lutaml-model#745).
|
|
425
|
+
def self.evaluating_default
|
|
426
|
+
previous = Thread.current[:__lutaml_evaluating_default]
|
|
427
|
+
Thread.current[:__lutaml_evaluating_default] = true
|
|
428
|
+
yield
|
|
429
|
+
ensure
|
|
430
|
+
Thread.current[:__lutaml_evaluating_default] = previous
|
|
431
|
+
end
|
|
432
|
+
|
|
433
|
+
def self.default_evaluation?
|
|
434
|
+
Thread.current[:__lutaml_evaluating_default] == true
|
|
435
|
+
end
|
|
436
|
+
|
|
408
437
|
def default_set?(register, instance_object = nil)
|
|
409
438
|
!Utils.uninitialized?(default_value(register, instance_object))
|
|
410
439
|
end
|
|
@@ -478,7 +507,10 @@ instance_object = nil)
|
|
|
478
507
|
# Use the default value if the value is nil
|
|
479
508
|
validate_required!(value)
|
|
480
509
|
|
|
481
|
-
|
|
510
|
+
if value.nil?
|
|
511
|
+
value = cast_value(default_value(register, instance_object),
|
|
512
|
+
register)
|
|
513
|
+
end
|
|
482
514
|
resolved_type = type(register)
|
|
483
515
|
|
|
484
516
|
valid_value!(value) &&
|
|
@@ -551,7 +583,8 @@ instance_object = nil)
|
|
|
551
583
|
end
|
|
552
584
|
|
|
553
585
|
def valid_collection!(value, caller)
|
|
554
|
-
if collection_instance?(value) && !collection?
|
|
586
|
+
if collection_instance?(value) && !collection? &&
|
|
587
|
+
!value_policy.whole_value?(unresolved_type)
|
|
555
588
|
raise Lutaml::Model::CollectionTrueMissingError.new(name,
|
|
556
589
|
caller)
|
|
557
590
|
end
|
|
@@ -632,7 +665,8 @@ instance_object = nil)
|
|
|
632
665
|
else
|
|
633
666
|
type(register)
|
|
634
667
|
end
|
|
635
|
-
if collection_instance?(value) || value.is_a?(Array)
|
|
668
|
+
if (collection_instance?(value) || value.is_a?(Array)) &&
|
|
669
|
+
!value_policy.whole_value?(resolved_type)
|
|
636
670
|
merged_opts = options.merge(resolved_type: resolved_type,
|
|
637
671
|
converted: true)
|
|
638
672
|
return build_collection(value.map do |v|
|
|
@@ -192,7 +192,7 @@ module Lutaml
|
|
|
192
192
|
# @param args [Array] Arguments (ignored for options)
|
|
193
193
|
# @param block [Proc] Block (ignored for options)
|
|
194
194
|
# @return [Object] The option value or nil
|
|
195
|
-
def method_missing(method_name, *args, &)
|
|
195
|
+
def method_missing(method_name, *args, &block)
|
|
196
196
|
# Check if this is an option key
|
|
197
197
|
if options.key?(method_name)
|
|
198
198
|
return options[method_name]
|
data/lib/lutaml/model/config.rb
CHANGED
|
@@ -42,8 +42,8 @@ module Lutaml
|
|
|
42
42
|
# Config.with_adapter(xml: :nokogiri, toml: :tomlib) do
|
|
43
43
|
# MyModel.from_xml(data)
|
|
44
44
|
# end
|
|
45
|
-
def with_adapter(**overrides, &)
|
|
46
|
-
AdapterScope.with(overrides, &)
|
|
45
|
+
def with_adapter(**overrides, &block)
|
|
46
|
+
AdapterScope.with(overrides, &block)
|
|
47
47
|
end
|
|
48
48
|
|
|
49
49
|
# Delegate configure to Configuration
|
|
@@ -39,8 +39,8 @@ module Lutaml
|
|
|
39
39
|
end
|
|
40
40
|
|
|
41
41
|
# Pattern A: declare discriminator routing
|
|
42
|
-
def dispatch_by(discriminator, &)
|
|
43
|
-
routes = DispatchBuilder.new.evaluate(&)
|
|
42
|
+
def dispatch_by(discriminator, &block)
|
|
43
|
+
routes = DispatchBuilder.new.evaluate(&block)
|
|
44
44
|
@rules << DispatchBlock.new(discriminator, routes)
|
|
45
45
|
end
|
|
46
46
|
|
data/lib/lutaml/model/errors.rb
CHANGED
|
@@ -436,8 +436,10 @@ context_id = nil)
|
|
|
436
436
|
instance.register_for_namespace(namespace_uri)
|
|
437
437
|
end
|
|
438
438
|
|
|
439
|
-
def resolve_type_with_namespace(type_name, namespace_uri = nil,
|
|
440
|
-
|
|
439
|
+
def resolve_type_with_namespace(type_name, namespace_uri = nil,
|
|
440
|
+
context_id = nil)
|
|
441
|
+
instance.resolve_type_with_namespace(type_name, namespace_uri,
|
|
442
|
+
context_id)
|
|
441
443
|
end
|
|
442
444
|
|
|
443
445
|
def namespace_register_map
|
|
@@ -67,6 +67,9 @@ module Lutaml
|
|
|
67
67
|
)
|
|
68
68
|
@name = name
|
|
69
69
|
@to = to
|
|
70
|
+
# Dynamic symbol built per call allocated ~10% of parse objects on
|
|
71
|
+
# attribute-heavy documents; `to` is immutable, so build it once.
|
|
72
|
+
@setter_name = :"#{to}="
|
|
70
73
|
@to_instance = to_instance
|
|
71
74
|
@as_attribute = as_attribute
|
|
72
75
|
@render_nil = render_nil
|
|
@@ -457,7 +460,7 @@ module Lutaml
|
|
|
457
460
|
end
|
|
458
461
|
|
|
459
462
|
def assign_value(model, value)
|
|
460
|
-
model.public_send(
|
|
463
|
+
model.public_send(@setter_name, value)
|
|
461
464
|
end
|
|
462
465
|
end
|
|
463
466
|
end
|
|
@@ -43,7 +43,7 @@ module Lutaml
|
|
|
43
43
|
to: nil,
|
|
44
44
|
transform: nil,
|
|
45
45
|
reverse_transform: nil,
|
|
46
|
-
&
|
|
46
|
+
&block
|
|
47
47
|
)
|
|
48
48
|
map(
|
|
49
49
|
from: from,
|
|
@@ -51,7 +51,7 @@ module Lutaml
|
|
|
51
51
|
transform: transform,
|
|
52
52
|
reverse_transform: reverse_transform,
|
|
53
53
|
collection: true,
|
|
54
|
-
&
|
|
54
|
+
&block
|
|
55
55
|
)
|
|
56
56
|
end
|
|
57
57
|
|
|
@@ -114,8 +114,8 @@ if Lutaml::Model::RuntimeCompatibility.opal?
|
|
|
114
114
|
|
|
115
115
|
# Minimal method_missing so the WeakRef quacks like its target
|
|
116
116
|
# for the Store's index lookups.
|
|
117
|
-
def method_missing(name,
|
|
118
|
-
@__target__.public_send(name,
|
|
117
|
+
def method_missing(name, ...)
|
|
118
|
+
@__target__.public_send(name, ...)
|
|
119
119
|
end
|
|
120
120
|
|
|
121
121
|
def respond_to_missing?(name, include_private = false)
|
|
@@ -36,7 +36,8 @@ module Lutaml
|
|
|
36
36
|
|
|
37
37
|
def load
|
|
38
38
|
Dir.mktmpdir do |dir|
|
|
39
|
-
FileWriter.write(@output, dir,
|
|
39
|
+
FileWriter.write(@output, dir,
|
|
40
|
+
registry_generator: @registry_generator)
|
|
40
41
|
require File.join(dir, "#{registry_basename}_registry")
|
|
41
42
|
call_register_all
|
|
42
43
|
end
|