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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d57b531de09099b0f55b1891c2b0dfec1a04fa75229a40c5c6b974f3be92fcda
4
- data.tar.gz: a893710f75fde8b5465360b95e6e772ba35711311a719ac35704a9a8ea7788ca
3
+ metadata.gz: 75da66a7985ef5c93b6c5f93a660046026a158b85a422cf924ce7a641f57d488
4
+ data.tar.gz: 5b3cbb99bd8c4398dec561c3885c2d996dd0491a0ba44d074549cc09c55cb59b
5
5
  SHA512:
6
- metadata.gz: b9ef9798066d2ec69567a2cfb9277d0058b933b640df9c6c240c1010a626560c27cdd722d10a474deddf70560f902bf58d41e35d1e2d1a8aa0fe83a9451afb2a
7
- data.tar.gz: 2c2bd13597f84afecd1aaf6fa4686db48048e371b014c55cb8c5993668eec38781e8b02ccd85a8ae5b68da8b3ea68056db87be7830128d35735c69f098711ff0
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 with the data modeling
17
- API of https://www.shalerb.org[Shale], an impressive Ruby data modeller.
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
- Core Model Serialization Model
99
- ========== ===================
100
- │ (mapping)
101
- │ │
102
- ▼ ▼
103
- Model XML Model
104
-
105
- ┌─────┴─────┐ ┌──────┴──────┐
106
- │ │ │ │
107
- Models Value Types ────┬──► Models Value Types
108
- │ │ │ │ │
109
- │ │ │ │ │
110
- │ ┌──────┴──┐ │ ┌────┴────┐ ┌─┴─┐
111
- │ │ │ │ │ │ │ │
112
- │ String Integer Element Value xs:string
113
- │ Date Float │ Attribute Type xs:date
114
- │ Time Boolean xs:boolean
115
- │ xs:anyURI
116
- └──────┐
117
- JSON Model
118
- Contains
119
- more Models │ ┌──────┴──────┐
120
- (recursive) │
121
- └──► Models Value Types
122
- │ │
123
- │ │
124
- ┌────┴────┐ ┌─┴─┐
125
- │ │
126
- object array number string
127
- value boolean null
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 if Utils.blank?(value) && !rule.render_nil
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 if Utils.blank?(attr_value)
383
+ next unless mapping_rule&.render?(attr_value)
380
384
 
381
385
  if path == :key
382
386
  map_key = attr_value
@@ -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
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Lutaml
4
4
  module Model
5
- VERSION = "0.5.2"
5
+ VERSION = "0.5.3"
6
6
  end
7
7
  end
@@ -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.2
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-10 00:00:00.000000000 Z
11
+ date: 2025-01-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor