lutaml-model 0.5.2 → 0.5.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.adoc +37 -32
- data/lib/lutaml/model/mapping_rule.rb +4 -0
- data/lib/lutaml/model/serialize.rb +9 -5
- data/lib/lutaml/model/utils.rb +7 -0
- data/lib/lutaml/model/version.rb +1 -1
- data/spec/lutaml/model/render_nil_spec.rb +29 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 75da66a7985ef5c93b6c5f93a660046026a158b85a422cf924ce7a641f57d488
|
4
|
+
data.tar.gz: 5b3cbb99bd8c4398dec561c3885c2d996dd0491a0ba44d074549cc09c55cb59b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '04728da10c80f08e47645646f4f06bbc796b074f8f1941594574f1d69fee96c32882b3db69d02b2f7878822b84423a46c81bb8a5ebb118d5b9c97533c0553e46'
|
7
|
+
data.tar.gz: 06cc0fcbb12ea5fc260eb25b3ecf3c5fc204738df760c5e33468b285007a4c0f0bd955e00ce1c128267c11f97d943f9a1f24b55c3a799ff3d730d0453c602bd8
|
data/README.adoc
CHANGED
@@ -13,8 +13,9 @@ objects to and from various formats such as JSON, XML, YAML, and TOML. It uses
|
|
13
13
|
an adapter pattern to support multiple libraries for each format, providing
|
14
14
|
flexibility and extensibility for your data modeling needs.
|
15
15
|
|
16
|
-
NOTE: Lutaml::Model is designed to be mostly compatible
|
17
|
-
API of https://www.shalerb.org[Shale],
|
16
|
+
NOTE: The Lutaml::Model modeling Ruby API is designed to be mostly compatible
|
17
|
+
with the data modeling API of https://www.shalerb.org[Shale], a data modeller
|
18
|
+
for Ruby.
|
18
19
|
Lutaml::Model is meant to address advanced needs not currently addressed by
|
19
20
|
Shale.
|
20
21
|
|
@@ -95,36 +96,39 @@ Studio (Model)
|
|
95
96
|
.Modeling relationships of a LutaML Model to serialization models
|
96
97
|
[source]
|
97
98
|
----
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
Models Value Types
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
99
|
+
╔═══════════════════════╗ ╔════════════════════════════╗
|
100
|
+
║ Core Model ║ ║ Serialization Models ║
|
101
|
+
╚═══════════════════════╝ ╚════════════════════════════╝
|
102
|
+
|
103
|
+
╭┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄╮ ╭┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄╮
|
104
|
+
┆ Model ┆ ┆ XML Model ┆
|
105
|
+
┆ │ ┆ ┌────────────────┐ ┆ │ ┆
|
106
|
+
┆ ┌────────┴──┐ ┆ │ │ ┆ ┌──────┴──────┐ ┆
|
107
|
+
┆ │ │ ┆ │ Model │ ┆ │ │ ┆
|
108
|
+
┆ Models Value Types ┆──►│ Transformation │ ┆ Models Value Types ┆
|
109
|
+
┆ │ │ ┆ │ & │ ┆ │ │ ┆
|
110
|
+
┆ │ │ ┆ │ Mapping Rules │ ┆ │ │ ┆
|
111
|
+
┆ │ ┌──────┴──┐ ┆ │ │ ┆ ┌────┴────┐ ┌─┴─┐ ┆
|
112
|
+
┆ │ │ │ ┆ │ │ ┆ │ │ │ │ ┆
|
113
|
+
┆ │ String Integer ┆ └────────────────┘ ┆ Element Value xs:string ┆
|
114
|
+
┆ │ Date Float ┆ │ ┆ Attribute Type xs:date ┆
|
115
|
+
┆ │ Time Boolean ┆ ├──────► ┆ xs:boolean ┆
|
116
|
+
┆ │ ┆ │ ┆ xs:anyURI ┆
|
117
|
+
┆ └──────┐ ┆ │ ╰┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄╯
|
118
|
+
┆ │ ┆ │
|
119
|
+
┆ Contains ┆ │ ╭┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄╮
|
120
|
+
┆ more Models ┆ │ ┆ JSON Model ┆
|
121
|
+
┆ (recursive) ┆ │ ┆ │ ┆
|
122
|
+
┆ ┆ │ ┆ ┌──────┴──────┐ ┆
|
123
|
+
╰┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄╯ └───────► ┆ │ │ ┆
|
124
|
+
┆ Models Value Types ┆
|
125
|
+
┆ │ │ ┆
|
126
|
+
┆ │ │ ┆
|
127
|
+
┆ ┌────┴───┐ ┌───┴──┐ ┆
|
128
|
+
┆ │ │ │ │ ┆
|
129
|
+
┆ object array number string ┆
|
130
|
+
┆ value boolean null ┆
|
131
|
+
╰┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄╯
|
128
132
|
----
|
129
133
|
|
130
134
|
.Example of LutaML Model instance transformed into a serialization model and serialized to JSON
|
@@ -278,6 +282,7 @@ attribute :name_of_attribute, {symbol | string | class}
|
|
278
282
|
| `:time` | `Time` | `xs:dateTime` | `string` | `string` | `"2024-01-01T12:00:00+00:00"`
|
279
283
|
| `:decimal` (optional) | `BigDecimal` | `xs:decimal` | `number` | `float` | `123.45`
|
280
284
|
| `:hash` | `Hash` | complex element | object | map | `{key: "value"}`
|
285
|
+
| (nil value) | `nil` | `xs:anyType` | `null` | `null` | `null`
|
281
286
|
// | `class` | Custom class | complex element | object | map | `CustomObject`
|
282
287
|
// | `collection: true` | `Array` of type | repeated elements | array | sequence | `[obj1, obj2]`
|
283
288
|
// | `any`
|
@@ -34,6 +34,10 @@ module Lutaml
|
|
34
34
|
alias render_default? render_default
|
35
35
|
alias attribute? attribute
|
36
36
|
|
37
|
+
def render?(value)
|
38
|
+
render_nil? || (!value.nil? && !Utils.empty_collection?(value))
|
39
|
+
end
|
40
|
+
|
37
41
|
def serialize_attribute(model, element, doc)
|
38
42
|
if custom_methods[:to]
|
39
43
|
model.send(custom_methods[:to], model, element, doc)
|
@@ -271,15 +271,15 @@ module Lutaml
|
|
271
271
|
|
272
272
|
attribute = attributes[name]
|
273
273
|
|
274
|
-
next hash.merge!(generate_hash_from_child_mappings(value, format, rule.root_mappings)) if rule.root_mapping?
|
274
|
+
next hash.merge!(generate_hash_from_child_mappings(attribute, value, format, rule.root_mappings)) if rule.root_mapping?
|
275
275
|
|
276
276
|
value = if rule.child_mappings
|
277
|
-
generate_hash_from_child_mappings(value, format, rule.child_mappings)
|
277
|
+
generate_hash_from_child_mappings(attribute, value, format, rule.child_mappings)
|
278
278
|
else
|
279
279
|
attribute.serialize(value, format, options)
|
280
280
|
end
|
281
281
|
|
282
|
-
next
|
282
|
+
next unless rule.render?(value)
|
283
283
|
|
284
284
|
rule_from_name = rule.multiple_mappings? ? rule.from.first.to_s : rule.from.to_s
|
285
285
|
hash[rule_from_name] = value
|
@@ -346,7 +346,7 @@ module Lutaml
|
|
346
346
|
end
|
347
347
|
end
|
348
348
|
|
349
|
-
def generate_hash_from_child_mappings(value, format, child_mappings)
|
349
|
+
def generate_hash_from_child_mappings(attr, value, format, child_mappings)
|
350
350
|
return value unless child_mappings
|
351
351
|
|
352
352
|
hash = {}
|
@@ -365,7 +365,11 @@ module Lutaml
|
|
365
365
|
value.each do |child_obj|
|
366
366
|
map_key = nil
|
367
367
|
map_value = {}
|
368
|
+
mapping_rules = attr.type.mappings_for(format)
|
369
|
+
|
368
370
|
child_mappings.each do |attr_name, path|
|
371
|
+
mapping_rule = mapping_rules.find_by_to(attr_name)
|
372
|
+
|
369
373
|
attr_value = child_obj.send(attr_name)
|
370
374
|
|
371
375
|
attr_value = if attr_value.is_a?(Lutaml::Model::Serialize)
|
@@ -376,7 +380,7 @@ module Lutaml
|
|
376
380
|
attr_value
|
377
381
|
end
|
378
382
|
|
379
|
-
next
|
383
|
+
next unless mapping_rule&.render?(attr_value)
|
380
384
|
|
381
385
|
if path == :key
|
382
386
|
map_key = attr_value
|
data/lib/lutaml/model/utils.rb
CHANGED
@@ -42,6 +42,13 @@ module Lutaml
|
|
42
42
|
value.respond_to?(:empty?) ? value.empty? : value.nil?
|
43
43
|
end
|
44
44
|
|
45
|
+
def empty_collection?(collection)
|
46
|
+
return false if collection.nil?
|
47
|
+
return false unless [Array, Hash].include?(collection.class)
|
48
|
+
|
49
|
+
collection.empty?
|
50
|
+
end
|
51
|
+
|
45
52
|
def add_method_if_not_defined(klass, method_name, &block)
|
46
53
|
unless klass.method_defined?(method_name)
|
47
54
|
klass.class_eval do
|
data/lib/lutaml/model/version.rb
CHANGED
@@ -136,4 +136,33 @@ RSpec.describe RenderNil do
|
|
136
136
|
expect(pottery.name).to eq("Unnamed Pottery")
|
137
137
|
expect(pottery.glaze).to be_nil
|
138
138
|
end
|
139
|
+
|
140
|
+
context "with empty string as values for attributes" do
|
141
|
+
let(:attributes) do
|
142
|
+
{
|
143
|
+
name: "",
|
144
|
+
clay_type: "",
|
145
|
+
glaze: "",
|
146
|
+
dimensions: [],
|
147
|
+
render_nil_nested: RenderNilNested.new,
|
148
|
+
}
|
149
|
+
end
|
150
|
+
|
151
|
+
it "does not tread empty string as nil" do
|
152
|
+
expected_yaml = <<~YAML
|
153
|
+
---
|
154
|
+
name: ''
|
155
|
+
clay_type: ''
|
156
|
+
glaze: ''
|
157
|
+
YAML
|
158
|
+
|
159
|
+
generated_yaml = model.to_yaml.strip
|
160
|
+
|
161
|
+
# Removing empty spaces from the end of the line because of and issue in
|
162
|
+
# libyaml -> https://github.com/yaml/libyaml/issues/46
|
163
|
+
generated_yaml = generated_yaml.gsub(": \n", ":\n")
|
164
|
+
|
165
|
+
expect(generated_yaml).to eq(expected_yaml.strip)
|
166
|
+
end
|
167
|
+
end
|
139
168
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lutaml-model
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ribose Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-01-
|
11
|
+
date: 2025-01-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|