lutaml-model 0.7.1 → 0.7.7
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/dependent-tests.yml +4 -0
- data/.github/workflows/rake.yml +12 -0
- data/.github/workflows/release.yml +3 -0
- data/.gitignore +6 -1
- data/.irbrc +1 -0
- data/.pryrc +1 -0
- data/.rubocop.yml +1 -1
- data/.rubocop_todo.yml +58 -84
- data/Gemfile +4 -1
- data/README.adoc +3115 -365
- data/RELEASE_NOTES.adoc +346 -0
- data/docs/custom_adapters.adoc +144 -0
- 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 +242 -100
- data/lib/lutaml/model/choice.rb +30 -0
- data/lib/lutaml/model/collection.rb +212 -0
- data/lib/lutaml/model/comparable_model.rb +3 -3
- data/lib/lutaml/model/config.rb +71 -42
- 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/polymorphic_error.rb +7 -2
- 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 +44 -0
- data/lib/lutaml/model/global_register.rb +41 -0
- data/lib/lutaml/model/hash_adapter/document.rb +11 -0
- data/lib/lutaml/model/hash_adapter/mapping.rb +19 -0
- data/lib/lutaml/model/hash_adapter/mapping_rule.rb +9 -0
- data/lib/lutaml/model/hash_adapter/standard_adapter.rb +17 -0
- data/lib/lutaml/model/hash_adapter/transform.rb +8 -0
- data/lib/lutaml/model/hash_adapter.rb +21 -0
- data/lib/lutaml/model/json/document.rb +11 -0
- data/lib/lutaml/model/json/mapping.rb +19 -0
- data/lib/lutaml/model/json/mapping_rule.rb +9 -0
- data/lib/lutaml/model/{json_adapter → json}/multi_json_adapter.rb +4 -5
- data/lib/lutaml/model/{json_adapter/standard_json_adapter.rb → json/standard_adapter.rb} +5 -3
- data/lib/lutaml/model/json/transform.rb +8 -0
- data/lib/lutaml/model/json.rb +21 -0
- 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 +28 -0
- data/lib/lutaml/model/mapping/key_value_mapping.rb +85 -13
- data/lib/lutaml/model/mapping/key_value_mapping_rule.rb +5 -0
- data/lib/lutaml/model/mapping/mapping.rb +13 -0
- data/lib/lutaml/model/mapping/mapping_rule.rb +15 -9
- data/lib/lutaml/model/register.rb +105 -0
- data/lib/lutaml/model/{toml_adapter.rb → registrable.rb} +1 -1
- 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/serialization_adapter.rb +22 -0
- data/lib/lutaml/model/serialize.rb +296 -548
- data/lib/lutaml/model/services/base.rb +11 -0
- data/lib/lutaml/model/services/logger.rb +54 -0
- data/lib/lutaml/model/services/rule_value_extractor.rb +92 -0
- data/lib/lutaml/model/services/transformer.rb +48 -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 +5 -0
- data/lib/lutaml/model/toml/document.rb +11 -0
- data/lib/lutaml/model/toml/mapping.rb +27 -0
- data/lib/lutaml/model/toml/mapping_rule.rb +9 -0
- data/lib/lutaml/model/{toml_adapter → toml}/toml_rb_adapter.rb +3 -3
- data/lib/lutaml/model/toml/tomlib_adapter.rb +19 -0
- data/lib/lutaml/model/toml/transform.rb +8 -0
- data/lib/lutaml/model/toml.rb +30 -0
- data/lib/lutaml/model/transform/key_value_transform.rb +297 -0
- data/lib/lutaml/model/transform/xml_transform.rb +228 -0
- data/lib/lutaml/model/transform.rb +93 -0
- 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 +11 -10
- data/lib/lutaml/model/type.rb +5 -2
- data/lib/lutaml/model/uninitialized_class.rb +1 -1
- data/lib/lutaml/model/utils.rb +56 -4
- data/lib/lutaml/model/validation.rb +6 -4
- data/lib/lutaml/model/version.rb +1 -1
- data/lib/lutaml/model/{xml_adapter → xml}/builder/nokogiri.rb +2 -2
- data/lib/lutaml/model/{xml_adapter → xml}/builder/oga.rb +10 -10
- data/lib/lutaml/model/{xml_adapter → xml}/builder/ox.rb +1 -1
- data/lib/lutaml/model/{xml_adapter/xml_document.rb → xml/document.rb} +42 -25
- data/lib/lutaml/model/xml/element.rb +32 -0
- data/lib/lutaml/model/xml/mapping.rb +471 -0
- data/lib/lutaml/model/xml/mapping_rule.rb +149 -0
- data/lib/lutaml/model/xml/nokogiri_adapter.rb +234 -0
- data/lib/lutaml/model/{xml_adapter → xml}/oga/document.rb +1 -1
- data/lib/lutaml/model/{xml_adapter → xml}/oga/element.rb +7 -2
- data/lib/lutaml/model/xml/oga_adapter.rb +172 -0
- data/lib/lutaml/model/xml/ox_adapter.rb +229 -0
- data/lib/lutaml/model/xml/transform.rb +8 -0
- data/lib/lutaml/model/{xml_adapter → xml}/xml_attribute.rb +1 -1
- data/lib/lutaml/model/{xml_adapter → xml}/xml_element.rb +9 -31
- data/lib/lutaml/model/{xml_adapter → xml}/xml_namespace.rb +1 -1
- data/lib/lutaml/model/xml.rb +31 -0
- data/lib/lutaml/model/xml_adapter/element.rb +11 -25
- data/lib/lutaml/model/xml_adapter/nokogiri_adapter.rb +6 -223
- data/lib/lutaml/model/xml_adapter/oga_adapter.rb +13 -163
- data/lib/lutaml/model/xml_adapter/ox_adapter.rb +10 -207
- data/lib/lutaml/model/yaml/document.rb +10 -0
- data/lib/lutaml/model/yaml/mapping.rb +19 -0
- data/lib/lutaml/model/yaml/mapping_rule.rb +9 -0
- data/lib/lutaml/model/{yaml_adapter/standard_yaml_adapter.rb → yaml/standard_adapter.rb} +4 -3
- data/lib/lutaml/model/yaml/transform.rb +8 -0
- data/lib/lutaml/model/yaml.rb +21 -0
- 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 +15 -4
- data/lutaml-model.gemspec +0 -4
- data/spec/benchmarks/xml_parsing_benchmark_spec.rb +5 -6
- 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/cdata_spec.rb +7 -7
- data/spec/lutaml/model/choice_spec.rb +44 -0
- data/spec/lutaml/model/custom_bibtex_adapter_spec.rb +598 -0
- data/spec/lutaml/model/custom_collection_spec.rb +830 -0
- data/spec/lutaml/model/custom_vobject_adapter_spec.rb +1226 -0
- data/spec/lutaml/model/global_register_spec.rb +108 -0
- data/spec/lutaml/model/group_spec.rb +27 -10
- data/spec/lutaml/model/hash/adapter_spec.rb +255 -0
- data/spec/lutaml/model/json_adapter_spec.rb +6 -6
- data/spec/lutaml/model/jsonl/standard_adapter_spec.rb +91 -0
- data/spec/lutaml/model/jsonl_spec.rb +229 -0
- data/spec/lutaml/model/key_value_mapping_spec.rb +25 -1
- data/spec/lutaml/model/mixed_content_spec.rb +24 -24
- data/spec/lutaml/model/multiple_mapping_spec.rb +6 -6
- data/spec/lutaml/model/ordered_content_spec.rb +6 -6
- data/spec/lutaml/model/polymorphic_spec.rb +178 -0
- data/spec/lutaml/model/register/key_value_spec.rb +275 -0
- data/spec/lutaml/model/register/xml_spec.rb +185 -0
- data/spec/lutaml/model/register_spec.rb +147 -0
- data/spec/lutaml/model/root_mappings_spec.rb +3 -3
- 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 +201 -94
- data/spec/lutaml/model/toml_adapter_spec.rb +6 -6
- data/spec/lutaml/model/toml_spec.rb +51 -0
- data/spec/lutaml/model/transformation_spec.rb +72 -15
- data/spec/lutaml/model/type_spec.rb +8 -4
- data/spec/lutaml/model/uninitialized_class_spec.rb +96 -0
- 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/namespace_spec.rb +57 -0
- data/spec/lutaml/model/xml/root_mappings/nested_child_mappings_spec.rb +217 -0
- data/spec/lutaml/model/xml/xml_element_spec.rb +7 -1
- data/spec/lutaml/model/xml_adapter/nokogiri_adapter_spec.rb +2 -2
- data/spec/lutaml/model/xml_adapter/oga_adapter_spec.rb +2 -2
- data/spec/lutaml/model/xml_adapter/ox_adapter_spec.rb +2 -2
- data/spec/lutaml/model/xml_adapter/xml_namespace_spec.rb +12 -12
- data/spec/lutaml/model/xml_adapter_spec.rb +30 -6
- data/spec/lutaml/model/xml_mapping_rule_spec.rb +14 -7
- data/spec/lutaml/model/xml_mapping_spec.rb +27 -15
- data/spec/lutaml/model/xml_spec.rb +63 -0
- data/spec/lutaml/model/yaml_adapter_spec.rb +3 -5
- 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 +4 -3
- metadata +162 -60
- data/lib/lutaml/model/json_adapter/json_document.rb +0 -20
- data/lib/lutaml/model/json_adapter/json_object.rb +0 -28
- data/lib/lutaml/model/loggable.rb +0 -15
- data/lib/lutaml/model/mapping/json_mapping.rb +0 -17
- data/lib/lutaml/model/mapping/toml_mapping.rb +0 -25
- data/lib/lutaml/model/mapping/xml_mapping.rb +0 -389
- data/lib/lutaml/model/mapping/xml_mapping_rule.rb +0 -139
- data/lib/lutaml/model/mapping/yaml_mapping.rb +0 -17
- data/lib/lutaml/model/mapping.rb +0 -14
- data/lib/lutaml/model/schema/templates/simple_type.rb +0 -247
- data/lib/lutaml/model/toml_adapter/toml_document.rb +0 -20
- data/lib/lutaml/model/toml_adapter/toml_object.rb +0 -28
- data/lib/lutaml/model/toml_adapter/tomlib_adapter.rb +0 -20
- data/lib/lutaml/model/yaml_adapter/yaml_document.rb +0 -20
- data/lib/lutaml/model/yaml_adapter/yaml_object.rb +0 -28
- data/lib/lutaml/model/yaml_adapter.rb +0 -8
|
@@ -2,31 +2,34 @@ module Lutaml
|
|
|
2
2
|
module Model
|
|
3
3
|
module Type
|
|
4
4
|
class Integer < Value
|
|
5
|
-
def self.cast(value)
|
|
5
|
+
def self.cast(value, options = {})
|
|
6
6
|
return nil if value.nil?
|
|
7
7
|
return 1 if value === true
|
|
8
8
|
return 0 if value === false
|
|
9
9
|
|
|
10
|
-
case value
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
10
|
+
value = case value
|
|
11
|
+
when ::String
|
|
12
|
+
if value.match?(/^0[0-7]+$/) # Octal
|
|
13
|
+
value.to_i(8)
|
|
14
|
+
elsif value.match?(/^-?\d+(\.\d+)?(e-?\d+)?$/i) # Float/exponential
|
|
15
|
+
Float(value).to_i
|
|
16
|
+
else
|
|
17
|
+
begin
|
|
18
|
+
Integer(value, 10)
|
|
19
|
+
rescue StandardError
|
|
20
|
+
nil
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
else
|
|
24
|
+
begin
|
|
25
|
+
Integer(value)
|
|
26
|
+
rescue StandardError
|
|
27
|
+
nil
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
Model::Services::Type::Validator::Number.validate!(value, options)
|
|
32
|
+
value
|
|
30
33
|
end
|
|
31
34
|
|
|
32
35
|
# Override serialize to return Integer instead of String
|
|
@@ -2,10 +2,12 @@ module Lutaml
|
|
|
2
2
|
module Model
|
|
3
3
|
module Type
|
|
4
4
|
class String < Value
|
|
5
|
-
def self.cast(value)
|
|
5
|
+
def self.cast(value, options = {})
|
|
6
6
|
return nil if value.nil?
|
|
7
7
|
|
|
8
|
-
value.to_s
|
|
8
|
+
value = value.to_s
|
|
9
|
+
Model::Services::Type::Validator::String.validate!(value, options)
|
|
10
|
+
value
|
|
9
11
|
end
|
|
10
12
|
|
|
11
13
|
# xs:string format
|
|
@@ -11,7 +11,11 @@ module Lutaml
|
|
|
11
11
|
@value = self.class.cast(value)
|
|
12
12
|
end
|
|
13
13
|
|
|
14
|
-
def
|
|
14
|
+
def initialized?
|
|
15
|
+
true
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def self.cast(value, _options = {})
|
|
15
19
|
return nil if value.nil?
|
|
16
20
|
|
|
17
21
|
value
|
|
@@ -28,20 +32,17 @@ module Lutaml
|
|
|
28
32
|
value.to_s
|
|
29
33
|
end
|
|
30
34
|
|
|
31
|
-
# Format-specific instance methods
|
|
32
|
-
::Lutaml::Model::Config::AVAILABLE_FORMATS.each do |format|
|
|
33
|
-
define_method(:"to_#{format}") do
|
|
34
|
-
value
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
|
|
38
35
|
# Class-level format conversion
|
|
39
36
|
def self.from_format(value, format)
|
|
40
37
|
new(send(:"from_#{format}", value))
|
|
41
38
|
end
|
|
42
39
|
|
|
43
|
-
#
|
|
44
|
-
|
|
40
|
+
# called from config when a new format is added
|
|
41
|
+
def self.register_format_to_from_methods(format)
|
|
42
|
+
define_method(:"to_#{format}") do
|
|
43
|
+
value
|
|
44
|
+
end
|
|
45
|
+
|
|
45
46
|
define_singleton_method(:"from_#{format}") do |value|
|
|
46
47
|
cast(value)
|
|
47
48
|
end
|
data/lib/lutaml/model/type.rb
CHANGED
|
@@ -5,6 +5,7 @@ module Lutaml
|
|
|
5
5
|
string: "Lutaml::Model::Type::String",
|
|
6
6
|
integer: "Lutaml::Model::Type::Integer",
|
|
7
7
|
float: "Lutaml::Model::Type::Float",
|
|
8
|
+
double: "Lutaml::Model::Type::Float",
|
|
8
9
|
decimal: "Lutaml::Model::Type::Decimal",
|
|
9
10
|
date: "Lutaml::Model::Type::Date",
|
|
10
11
|
time: "Lutaml::Model::Type::Time",
|
|
@@ -32,6 +33,8 @@ module Lutaml
|
|
|
32
33
|
end
|
|
33
34
|
|
|
34
35
|
def lookup(type_name)
|
|
36
|
+
return type_name if type_name.is_a?(Class)
|
|
37
|
+
|
|
35
38
|
@registry ||= {}
|
|
36
39
|
klass = @registry[type_name.to_sym]
|
|
37
40
|
|
|
@@ -43,13 +46,13 @@ module Lutaml
|
|
|
43
46
|
def cast(value, type)
|
|
44
47
|
return nil if value.nil?
|
|
45
48
|
|
|
46
|
-
type.cast(value)
|
|
49
|
+
lookup(type).cast(value)
|
|
47
50
|
end
|
|
48
51
|
|
|
49
52
|
def serialize(value, type)
|
|
50
53
|
return nil if value.nil?
|
|
51
54
|
|
|
52
|
-
type.serialize(value)
|
|
55
|
+
lookup(type).serialize(value)
|
|
53
56
|
end
|
|
54
57
|
end
|
|
55
58
|
end
|
data/lib/lutaml/model/utils.rb
CHANGED
|
@@ -4,6 +4,8 @@ module Lutaml
|
|
|
4
4
|
module Model
|
|
5
5
|
module Utils
|
|
6
6
|
class << self
|
|
7
|
+
UNINITIALIZED = Lutaml::Model::UninitializedClass.instance
|
|
8
|
+
|
|
7
9
|
# Convert string to camel case
|
|
8
10
|
def camel_case(str)
|
|
9
11
|
return "" if str.nil? || str.empty?
|
|
@@ -34,14 +36,22 @@ module Lutaml
|
|
|
34
36
|
.downcase
|
|
35
37
|
end
|
|
36
38
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
+
# Extract the base name of the class
|
|
40
|
+
def base_class_name(klass)
|
|
41
|
+
klass.to_s.split("::").last
|
|
42
|
+
end
|
|
39
43
|
|
|
40
|
-
|
|
44
|
+
# Convert the extracted base class to snake case format
|
|
45
|
+
def base_class_snake_case(klass)
|
|
46
|
+
snake_case(base_class_name(klass))
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def initialized?(value)
|
|
50
|
+
!value.equal?(UNINITIALIZED)
|
|
41
51
|
end
|
|
42
52
|
|
|
43
53
|
def uninitialized?(value)
|
|
44
|
-
|
|
54
|
+
value.equal?(UNINITIALIZED)
|
|
45
55
|
end
|
|
46
56
|
|
|
47
57
|
def present?(value)
|
|
@@ -63,6 +73,48 @@ module Lutaml
|
|
|
63
73
|
value.respond_to?(:empty?) ? value.empty? : false
|
|
64
74
|
end
|
|
65
75
|
|
|
76
|
+
def add_if_present(hash, key, value)
|
|
77
|
+
hash[key] = value if value
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Check if the hash contains the given key in string or symbol format
|
|
81
|
+
# @param hash [Hash] the hash to check
|
|
82
|
+
# @param key [String, Symbol] the key to check
|
|
83
|
+
# @return [Boolean] true if the hash contains the key, false otherwise
|
|
84
|
+
# @example
|
|
85
|
+
# hash = { "key" => "value" }
|
|
86
|
+
# string_or_symbol_key?(hash, "key") # => true
|
|
87
|
+
# string_or_symbol_key?(hash, :key) # => true
|
|
88
|
+
# string_or_symbol_key?(hash, "invalid_key") # => false
|
|
89
|
+
def string_or_symbol_key?(hash, key)
|
|
90
|
+
hash.key?(key.to_s) || hash.key?(key.to_sym)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# Fetch the value from the hash using the key in string or symbol format
|
|
94
|
+
# @param hash [Hash] the hash to fetch the value from
|
|
95
|
+
# @param key [String, Symbol] the key to fetch the value for
|
|
96
|
+
# @return [Object] the value associated with the key
|
|
97
|
+
# @example
|
|
98
|
+
# hash = { "key" => "value" }
|
|
99
|
+
# fetch_str_or_sym(hash, "key") # => "value"
|
|
100
|
+
# fetch_str_or_sym(hash, :key) # => "value"
|
|
101
|
+
# fetch_str_or_sym(hash, "invalid_key") # => nil
|
|
102
|
+
def fetch_str_or_sym(hash, key, default = nil)
|
|
103
|
+
if hash.key?(key.to_s)
|
|
104
|
+
hash[key.to_s]
|
|
105
|
+
elsif hash.key?(key.to_sym)
|
|
106
|
+
hash[key.to_sym]
|
|
107
|
+
else
|
|
108
|
+
default
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def add_singleton_method_if_not_defined(instance, method_name, &block)
|
|
113
|
+
return if instance.respond_to?(method_name)
|
|
114
|
+
|
|
115
|
+
instance.define_singleton_method(method_name, &block)
|
|
116
|
+
end
|
|
117
|
+
|
|
66
118
|
def add_method_if_not_defined(klass, method_name, &block)
|
|
67
119
|
unless klass.method_defined?(method_name)
|
|
68
120
|
klass.class_eval do
|
|
@@ -1,20 +1,22 @@
|
|
|
1
1
|
module Lutaml
|
|
2
2
|
module Model
|
|
3
3
|
module Validation
|
|
4
|
-
def validate
|
|
4
|
+
def validate(register: Lutaml::Model::Config.default_register)
|
|
5
5
|
errors = []
|
|
6
|
+
|
|
6
7
|
self.class.attributes.each do |name, attr|
|
|
7
8
|
value = public_send(:"#{name}")
|
|
8
9
|
begin
|
|
9
10
|
if value.respond_to?(:validate)
|
|
10
11
|
errors.concat(value.validate)
|
|
11
12
|
else
|
|
12
|
-
attr.validate_value!(value)
|
|
13
|
+
attr.validate_value!(value, register)
|
|
13
14
|
end
|
|
14
15
|
rescue Lutaml::Model::InvalidValueError,
|
|
15
16
|
Lutaml::Model::CollectionCountOutOfRangeError,
|
|
16
17
|
Lutaml::Model::CollectionTrueMissingError,
|
|
17
18
|
Lutaml::Model::PolymorphicError,
|
|
19
|
+
Lutaml::Model::ValidationFailedError,
|
|
18
20
|
PatternNotMatchedError => e
|
|
19
21
|
errors << e
|
|
20
22
|
end
|
|
@@ -23,8 +25,8 @@ module Lutaml
|
|
|
23
25
|
validate_helper(errors)
|
|
24
26
|
end
|
|
25
27
|
|
|
26
|
-
def validate!
|
|
27
|
-
errors = validate
|
|
28
|
+
def validate!(register: Lutaml::Model::Config.default_register)
|
|
29
|
+
errors = validate(register: register)
|
|
28
30
|
raise Lutaml::Model::ValidationError.new(errors) if errors.any?
|
|
29
31
|
end
|
|
30
32
|
|
data/lib/lutaml/model/version.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
module Lutaml
|
|
2
2
|
module Model
|
|
3
|
-
module
|
|
3
|
+
module Xml
|
|
4
4
|
module Builder
|
|
5
5
|
class Nokogiri
|
|
6
6
|
def self.build(options = {})
|
|
@@ -84,7 +84,7 @@ module Lutaml
|
|
|
84
84
|
end
|
|
85
85
|
|
|
86
86
|
def method_missing(method_name, *args, &block)
|
|
87
|
-
if
|
|
87
|
+
if block
|
|
88
88
|
xml.public_send(method_name, *args, &block)
|
|
89
89
|
else
|
|
90
90
|
xml.public_send(method_name, *args)
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
module Lutaml
|
|
4
4
|
module Model
|
|
5
|
-
module
|
|
5
|
+
module Xml
|
|
6
6
|
module Builder
|
|
7
7
|
class Oga
|
|
8
8
|
def self.build(options = {}, &block)
|
|
@@ -12,7 +12,7 @@ module Lutaml
|
|
|
12
12
|
attr_reader :document, :current_node, :encoding
|
|
13
13
|
|
|
14
14
|
def initialize(options = {})
|
|
15
|
-
@document =
|
|
15
|
+
@document = Xml::Oga::Document.new
|
|
16
16
|
@current_node = @document
|
|
17
17
|
@encoding = options[:encoding]
|
|
18
18
|
yield(self) if block_given?
|
|
@@ -23,7 +23,7 @@ module Lutaml
|
|
|
23
23
|
name = "#{@current_namespace}:#{name}"
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
-
if
|
|
26
|
+
if block
|
|
27
27
|
element(name, attributes, &block)
|
|
28
28
|
else
|
|
29
29
|
element(name, attributes)
|
|
@@ -48,9 +48,9 @@ module Lutaml
|
|
|
48
48
|
|
|
49
49
|
def add_element(oga_element, child)
|
|
50
50
|
if child.is_a?(String)
|
|
51
|
-
current_element = oga_element.is_a?(
|
|
51
|
+
current_element = oga_element.is_a?(Xml::Oga::Document) ? current_node : oga_element
|
|
52
52
|
add_xml_fragment(current_element, child)
|
|
53
|
-
elsif oga_element.is_a?(
|
|
53
|
+
elsif oga_element.is_a?(Xml::Oga::Document)
|
|
54
54
|
oga_element.children.last.children << child
|
|
55
55
|
else
|
|
56
56
|
oga_element.children << child
|
|
@@ -62,7 +62,7 @@ module Lutaml
|
|
|
62
62
|
name: name,
|
|
63
63
|
value: value.to_s,
|
|
64
64
|
)
|
|
65
|
-
if element.is_a?(
|
|
65
|
+
if element.is_a?(Xml::Oga::Document)
|
|
66
66
|
element.children.last.attributes << attribute
|
|
67
67
|
else
|
|
68
68
|
element.attributes << attribute
|
|
@@ -85,7 +85,7 @@ module Lutaml
|
|
|
85
85
|
element_name
|
|
86
86
|
end
|
|
87
87
|
|
|
88
|
-
if
|
|
88
|
+
if block
|
|
89
89
|
element(prefixed_name, attributes, &block)
|
|
90
90
|
else
|
|
91
91
|
element(prefixed_name, attributes)
|
|
@@ -100,7 +100,7 @@ module Lutaml
|
|
|
100
100
|
fragment = "<fragment>#{content}</fragment>"
|
|
101
101
|
parsed_fragment = ::Oga.parse_xml(fragment)
|
|
102
102
|
parsed_children = parsed_fragment.children.first.children
|
|
103
|
-
if element.is_a?(
|
|
103
|
+
if element.is_a?(Xml::Oga::Document)
|
|
104
104
|
element.children.last.children += parsed_children
|
|
105
105
|
else
|
|
106
106
|
element.children += parsed_children
|
|
@@ -116,7 +116,7 @@ module Lutaml
|
|
|
116
116
|
end
|
|
117
117
|
|
|
118
118
|
def append_text_node(element, oga_text)
|
|
119
|
-
if element.is_a?(
|
|
119
|
+
if element.is_a?(Xml::Oga::Document)
|
|
120
120
|
children = element.children
|
|
121
121
|
children.empty? ? children << oga_text : children.last.children << oga_text
|
|
122
122
|
else
|
|
@@ -126,7 +126,7 @@ module Lutaml
|
|
|
126
126
|
|
|
127
127
|
def add_cdata(element, value)
|
|
128
128
|
oga_cdata = ::Oga::XML::CData.new(text: value.to_s)
|
|
129
|
-
if element.is_a?(
|
|
129
|
+
if element.is_a?(Xml::Oga::Document)
|
|
130
130
|
element.children.last.children << oga_cdata
|
|
131
131
|
else
|
|
132
132
|
element.children << oga_cdata
|
|
@@ -6,13 +6,14 @@ require_relative "element"
|
|
|
6
6
|
|
|
7
7
|
module Lutaml
|
|
8
8
|
module Model
|
|
9
|
-
module
|
|
10
|
-
class
|
|
11
|
-
attr_reader :root, :encoding
|
|
9
|
+
module Xml
|
|
10
|
+
class Document
|
|
11
|
+
attr_reader :root, :encoding, :register
|
|
12
12
|
|
|
13
|
-
def initialize(root, encoding = nil)
|
|
13
|
+
def initialize(root, encoding = nil, register: nil)
|
|
14
14
|
@root = root
|
|
15
15
|
@encoding = encoding
|
|
16
|
+
@register = setup_register(register)
|
|
16
17
|
end
|
|
17
18
|
|
|
18
19
|
def self.parse(xml, _options = {})
|
|
@@ -79,7 +80,7 @@ module Lutaml
|
|
|
79
80
|
options[:mixed_content] = rule.mixed_content
|
|
80
81
|
options[:tag_name] = rule.name
|
|
81
82
|
|
|
82
|
-
options[:mapper_class] = attribute&.type if attribute
|
|
83
|
+
options[:mapper_class] = attribute&.type(register) if attribute
|
|
83
84
|
options[:set_namespace] = set_namespace?(rule)
|
|
84
85
|
|
|
85
86
|
options
|
|
@@ -107,7 +108,7 @@ module Lutaml
|
|
|
107
108
|
result["elements"] ||= Lutaml::Model::MappingHash.new
|
|
108
109
|
result["elements"].assign_or_append_value(
|
|
109
110
|
self.class.namespaced_name_of(child),
|
|
110
|
-
parse_element(child, attr&.type || klass, format),
|
|
111
|
+
parse_element(child, attr&.type(register) || klass, format),
|
|
111
112
|
)
|
|
112
113
|
end
|
|
113
114
|
|
|
@@ -127,9 +128,9 @@ module Lutaml
|
|
|
127
128
|
prefix: attr.namespace_prefix,
|
|
128
129
|
schema_location: attr.value,
|
|
129
130
|
}
|
|
131
|
+
else
|
|
132
|
+
result[attr.namespaced_name] = attr.value
|
|
130
133
|
end
|
|
131
|
-
|
|
132
|
-
result[attr.namespaced_name] = attr.value
|
|
133
134
|
end
|
|
134
135
|
|
|
135
136
|
result
|
|
@@ -148,17 +149,16 @@ module Lutaml
|
|
|
148
149
|
rule = options[:rule]
|
|
149
150
|
|
|
150
151
|
if rule.custom_methods[:to]
|
|
151
|
-
options[:mapper_class].new.send(rule.custom_methods[:to], element,
|
|
152
|
-
xml.parent, xml)
|
|
152
|
+
options[:mapper_class].new.send(rule.custom_methods[:to], element, xml.parent, xml)
|
|
153
153
|
return
|
|
154
154
|
end
|
|
155
155
|
|
|
156
156
|
# Only transform when recursion is not called
|
|
157
|
-
if
|
|
158
|
-
value =
|
|
157
|
+
if !attribute.collection? || attribute.collection_instance?(value)
|
|
158
|
+
value = ExportTransformer.call(value, rule, attribute)
|
|
159
159
|
end
|
|
160
160
|
|
|
161
|
-
if
|
|
161
|
+
if attribute.collection_instance?(value) && !Utils.empty_collection?(value)
|
|
162
162
|
value.each do |item|
|
|
163
163
|
add_to_xml(xml, element, prefix, item, options)
|
|
164
164
|
end
|
|
@@ -170,7 +170,7 @@ module Lutaml
|
|
|
170
170
|
|
|
171
171
|
value = rule.render_value_for(value)
|
|
172
172
|
|
|
173
|
-
if value && (attribute&.type&.<= Lutaml::Model::Serialize)
|
|
173
|
+
if value && (attribute&.type(register)&.<= Lutaml::Model::Serialize)
|
|
174
174
|
handle_nested_elements(
|
|
175
175
|
xml,
|
|
176
176
|
value,
|
|
@@ -195,10 +195,10 @@ module Lutaml
|
|
|
195
195
|
|
|
196
196
|
def add_value(xml, value, attribute, cdata: false)
|
|
197
197
|
if !value.nil?
|
|
198
|
-
serialized_value = attribute.serialize(value, :xml)
|
|
198
|
+
serialized_value = attribute.serialize(value, :xml, register)
|
|
199
199
|
if attribute.raw?
|
|
200
200
|
xml.add_xml_fragment(xml, value)
|
|
201
|
-
elsif attribute.type == Lutaml::Model::Type::Hash
|
|
201
|
+
elsif attribute.type(register) == Lutaml::Model::Type::Hash
|
|
202
202
|
serialized_value.each do |key, val|
|
|
203
203
|
xml.create_and_add_element(key) do |element|
|
|
204
204
|
element.text(val)
|
|
@@ -233,7 +233,6 @@ module Lutaml
|
|
|
233
233
|
end
|
|
234
234
|
|
|
235
235
|
mappings = xml_mapping.elements + [xml_mapping.raw_mapping].compact
|
|
236
|
-
|
|
237
236
|
mappings.each do |element_rule|
|
|
238
237
|
attribute_def = attribute_definition_for(element, element_rule,
|
|
239
238
|
mapper_class: mapper_class)
|
|
@@ -243,7 +242,7 @@ module Lutaml
|
|
|
243
242
|
|
|
244
243
|
next if !element_rule.render?(value, element)
|
|
245
244
|
|
|
246
|
-
value =
|
|
245
|
+
value = attribute_def.build_collection(value) if attribute_def.collection? && !attribute_def.collection_instance?(value)
|
|
247
246
|
end
|
|
248
247
|
|
|
249
248
|
add_to_xml(
|
|
@@ -265,14 +264,16 @@ module Lutaml
|
|
|
265
264
|
return unless content_rule
|
|
266
265
|
|
|
267
266
|
if content_rule.custom_methods[:to]
|
|
268
|
-
mapper_class.new.send(
|
|
269
|
-
|
|
267
|
+
mapper_class.new.send(
|
|
268
|
+
content_rule.custom_methods[:to],
|
|
269
|
+
element,
|
|
270
|
+
xml.parent,
|
|
271
|
+
xml,
|
|
272
|
+
)
|
|
270
273
|
else
|
|
271
274
|
text = content_rule.serialize(element)
|
|
272
275
|
text = text.join if text.is_a?(Array)
|
|
273
276
|
|
|
274
|
-
return unless content_rule.render?(text, element)
|
|
275
|
-
|
|
276
277
|
xml.add_text(xml, text, cdata: content_rule.cdata)
|
|
277
278
|
end
|
|
278
279
|
end
|
|
@@ -323,9 +324,10 @@ module Lutaml
|
|
|
323
324
|
processed[klass][mapping_rule.name] = true
|
|
324
325
|
|
|
325
326
|
type = if mapping_rule.delegate
|
|
326
|
-
attributes[mapping_rule.delegate].type
|
|
327
|
+
attributes[mapping_rule.delegate].type(register)
|
|
328
|
+
.attributes[mapping_rule.to].type(register)
|
|
327
329
|
else
|
|
328
|
-
attributes[mapping_rule.to]&.type
|
|
330
|
+
attributes[mapping_rule.to]&.type(register)
|
|
329
331
|
end
|
|
330
332
|
|
|
331
333
|
next unless type
|
|
@@ -366,7 +368,9 @@ module Lutaml
|
|
|
366
368
|
|
|
367
369
|
value = mapping_rule.to_value_for(element)
|
|
368
370
|
attr = attribute_definition_for(element, mapping_rule, mapper_class: options[:mapper_class])
|
|
369
|
-
value = attr.serialize(value, :xml) if attr
|
|
371
|
+
value = attr.serialize(value, :xml, register) if attr
|
|
372
|
+
|
|
373
|
+
value = ExportTransformer.call(value, mapping_rule, attr)
|
|
370
374
|
|
|
371
375
|
if render_element?(mapping_rule, element, value)
|
|
372
376
|
hash[mapping_rule.prefixed_name] = value ? value.to_s : value
|
|
@@ -434,6 +438,19 @@ module Lutaml
|
|
|
434
438
|
|
|
435
439
|
private
|
|
436
440
|
|
|
441
|
+
def setup_register(register)
|
|
442
|
+
return register if register.is_a?(Symbol)
|
|
443
|
+
|
|
444
|
+
return_register = if register.is_a?(Lutaml::Model::Register)
|
|
445
|
+
register.id
|
|
446
|
+
elsif @root.respond_to?(:__register)
|
|
447
|
+
@root.__register
|
|
448
|
+
elsif @root.instance_variable_defined?(:@__register)
|
|
449
|
+
@root.instance_variable_get(:@__register)
|
|
450
|
+
end
|
|
451
|
+
return_register || Lutaml::Model::Config.default_register
|
|
452
|
+
end
|
|
453
|
+
|
|
437
454
|
def determine_mapper_class(element, options)
|
|
438
455
|
if options[:mapper_class] && element.is_a?(options[:mapper_class])
|
|
439
456
|
element.class
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
module Lutaml
|
|
2
|
+
module Model
|
|
3
|
+
module Xml
|
|
4
|
+
class Element
|
|
5
|
+
attr_reader :type, :name
|
|
6
|
+
|
|
7
|
+
def initialize(type, name)
|
|
8
|
+
@type = type
|
|
9
|
+
@name = name
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def text?
|
|
13
|
+
@type == "Text" && @name != "#cdata-section"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def element_tag
|
|
17
|
+
@name unless text?
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def eql?(other)
|
|
21
|
+
return false unless other.is_a?(self.class)
|
|
22
|
+
|
|
23
|
+
instance_variables.all? do |var|
|
|
24
|
+
instance_variable_get(var) == other.instance_variable_get(var)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
alias == eql?
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|