lutaml-model 0.3.15 → 0.3.16

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: 59ac2ffbc292a5e34dbbbf79441a8220a48954ba5acd21d2780235281bfbbee2
4
- data.tar.gz: 253892694acb1359120e6401d83e05bc2daa2f371b69f667210c048c08f2336c
3
+ metadata.gz: b9687a8a307de8226b41a87abda56626627eefe47665628c0e9112b97f27385a
4
+ data.tar.gz: e819f531048e629d4943ea7b613815a568990f372ef2da93162d0d1b4d8395cd
5
5
  SHA512:
6
- metadata.gz: 920de33ce2cc20336fa2ed87c3a2d5743f4016c8a400a881c91e4eafee0452e3fdc110429f3e71b7216f84694e546b26848c50323bc25397d32c8a1aa2e6901e
7
- data.tar.gz: 3685a35624c0c355ee457241a308bf9e46c37c9a7b14994948a897c9210a13229c2a2832d8f595b2d83a4bf96660f1ea2b9843c83ea8ba9a73978ef67e864818
6
+ metadata.gz: f47d1336093db1eb45c5225913a9c63d66681de77d5803a21702baab0ca8e571e882a2d8f6f6dcf7b9180c897c9ae8bfd4b2db6532e9691487d104696657457e
7
+ data.tar.gz: 9ec8b8d841606d202acdcca81464761cc0f75e9ae5b35d2c3b8dd01c6e8a122642a348f41de2852b09386d3748eb61b1b2547df8d1ccb146a7d36e5a8ac46257
data/.rubocop_todo.yml CHANGED
@@ -1,12 +1,12 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config`
3
- # on 2024-10-23 12:15:48 UTC using RuboCop version 1.66.1.
3
+ # on 2024-10-28 08:29:46 UTC using RuboCop version 1.66.1.
4
4
  # The point is for the user to remove these configuration records
5
5
  # one by one as the offenses are removed from the code base.
6
6
  # Note that changes in the inspected code, or installation of new
7
7
  # versions of RuboCop, may require this file to be generated again.
8
8
 
9
- # Offense count: 139
9
+ # Offense count: 148
10
10
  # This cop supports safe autocorrection (--autocorrect).
11
11
  # Configuration parameters: Max, AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, AllowedPatterns.
12
12
  # URISchemes: http, https
@@ -69,7 +69,7 @@ Metrics/CyclomaticComplexity:
69
69
  Metrics/MethodLength:
70
70
  Max: 51
71
71
 
72
- # Offense count: 4
72
+ # Offense count: 6
73
73
  # Configuration parameters: CountKeywordArgs, MaxOptionalParameters.
74
74
  Metrics/ParameterLists:
75
75
  Max: 13
@@ -85,7 +85,7 @@ Metrics/PerceivedComplexity:
85
85
  - 'lib/lutaml/model/xml_adapter/ox_adapter.rb'
86
86
  - 'lib/lutaml/model/xml_adapter/xml_document.rb'
87
87
 
88
- # Offense count: 8
88
+ # Offense count: 9
89
89
  # Configuration parameters: Prefixes, AllowedPatterns.
90
90
  # Prefixes: when, with, without
91
91
  RSpec/ContextWording:
@@ -125,7 +125,7 @@ RSpec/MultipleDescribes:
125
125
  - 'spec/lutaml/model/xml_adapter/xml_namespace_spec.rb'
126
126
  - 'spec/lutaml/model/xml_adapter_spec.rb'
127
127
 
128
- # Offense count: 119
128
+ # Offense count: 125
129
129
  RSpec/MultipleExpectations:
130
130
  Max: 14
131
131
 
@@ -134,6 +134,11 @@ RSpec/MultipleExpectations:
134
134
  RSpec/MultipleMemoizedHelpers:
135
135
  Max: 9
136
136
 
137
+ # Offense count: 4
138
+ # Configuration parameters: AllowedGroups.
139
+ RSpec/NestedGroups:
140
+ Max: 4
141
+
137
142
  # Offense count: 7
138
143
  RSpec/PendingWithoutReason:
139
144
  Exclude:
@@ -153,13 +158,14 @@ RSpec/RepeatedExampleGroupDescription:
153
158
  Exclude:
154
159
  - 'spec/lutaml/model/collection_spec.rb'
155
160
 
156
- # Offense count: 2
161
+ # Offense count: 3
157
162
  # Configuration parameters: Include, CustomTransform, IgnoreMethods, IgnoreMetadata.
158
163
  # Include: **/*_spec.rb
159
164
  RSpec/SpecFilePathFormat:
160
165
  Exclude:
161
166
  - '**/spec/routing/**/*'
162
167
  - 'spec/lutaml/model/collection_spec.rb'
168
+ - 'spec/lutaml/model/defaults_spec.rb'
163
169
  - 'spec/lutaml/model/type/decimal_spec.rb'
164
170
 
165
171
  # Offense count: 1
data/README.adoc CHANGED
@@ -390,7 +390,7 @@ acceptance of the newly updated component.
390
390
  ====
391
391
 
392
392
 
393
- === Attribute value default
393
+ === Attribute value default and rendering defaults
394
394
 
395
395
  Specify default values for attributes using the `default` option.
396
396
  The `default` option can be set to a value or a lambda that returns a value.
@@ -423,6 +423,80 @@ end
423
423
  ----
424
424
  ====
425
425
 
426
+ The "default behavior" (pun intended) is to not render a default value if
427
+ the current value is the same as the default value.
428
+
429
+ In certain cases, it is necessary to render the default value even if the
430
+ current value is the same as the default value. This can be achieved by setting
431
+ the `render_default` option to `true`.
432
+
433
+ Syntax:
434
+
435
+ [source,ruby]
436
+ ----
437
+ attribute :name_of_attribute, Type, default: -> { value }, render_default: true
438
+ ----
439
+
440
+ .Using the `render_default` option to force encoding the default value
441
+ [example]
442
+ ====
443
+ [source,ruby]
444
+ ----
445
+ class Glaze < Lutaml::Model::Serializable
446
+ attribute :color, :string, default: -> { 'Clear' }
447
+ attribute :opacity, :string, default: -> { 'Opaque' }
448
+ attribute :temperature, :integer, default: -> { 1050 }
449
+ attribute :firing_time, :integer, default: -> { 60 }
450
+
451
+ xml do
452
+ root "glaze"
453
+ map_element 'color', to: :color
454
+ map_element 'opacity', to: :opacity, render_default: true
455
+ map_attribute 'temperature', to: :temperature
456
+ map_attribute 'firingTime', to: :firing_time, render_default: true
457
+ end
458
+
459
+ json do
460
+ map 'color', to: :color
461
+ map 'opacity', to: :opacity, render_default: true
462
+ map 'temperature', to: :temperature
463
+ map 'firingTime', to: :firing_time, render_default: true
464
+ end
465
+ end
466
+ ----
467
+
468
+ .Attributes with `render_default: true` are rendered when the value is identical to the default
469
+ [example]
470
+ ====
471
+ [source,ruby]
472
+ ----
473
+ > glaze_new = Glaze.new
474
+ > puts glaze_new.to_xml
475
+ # <glaze firingTime="60">
476
+ # <opacity>Opaque</opacity>
477
+ # </glaze>
478
+ > puts glaze_new.to_json
479
+ # {"firingTime":60,"opacity":"Opaque"}
480
+ ----
481
+ ====
482
+
483
+ .Attributes with `render_default: true` with non-default values are rendered
484
+ [example]
485
+ ====
486
+ [source,ruby]
487
+ ----
488
+ > glaze = Glaze.new(color: 'Celadon', opacity: 'Semitransparent', temperature: 1300, firing_time: 90)
489
+ > puts glaze.to_xml
490
+ # <glaze color="Celadon" temperature="1300" firingTime="90">
491
+ # <opacity>Semitransparent</opacity>
492
+ # </glaze>
493
+ > puts glaze.to_json
494
+ # {"color":"Celadon","temperature":1300,"firingTime":90,"opacity":"Semitransparent"}
495
+ ----
496
+ ====
497
+
498
+
499
+
426
500
  === Attribute as raw string
427
501
 
428
502
  An attribute can be set to read the value as raw string for XML, by using the `raw: true` option.
@@ -668,8 +742,10 @@ end
668
742
  > #<example value="12"></example>
669
743
  ----
670
744
 
671
- The map_attribute method does not inherit the root element's namespace. If you need to specify a namespace for an attribute,
672
- you must explicitly declare the namespace and prefix in the map_attribute method.
745
+ The `map_attribute` method does not inherit the root element's namespace.
746
+ To specify a namespace for an attribute, please explicitly declare the
747
+ *namespace* and *prefix* in the `map_attribute` method.
748
+
673
749
  [example]
674
750
  ====
675
751
  The following class will parse the XML snippet below:
@@ -1081,7 +1157,7 @@ end
1081
1157
  ----
1082
1158
  ====
1083
1159
 
1084
- TODO: How to create mixed content from `#new`?
1160
+ // TODO: How to create mixed content from `#new`?
1085
1161
 
1086
1162
  [[xml-schema-location]]
1087
1163
  ==== Automatic support of `xsi:schemaLocation`
@@ -2020,7 +2096,9 @@ Lutaml::Model::Config.configure do |config|
2020
2096
  end
2021
2097
  ----
2022
2098
 
2023
- NOTE: By default `yaml_adapter_type` and `json_adapter_type` are set to `:standard_yaml` and `:standard_json` respectively.
2099
+ NOTE: By default `yaml_adapter_type` and `json_adapter_type` are set to
2100
+ `:standard_yaml` and `:standard_json` respectively.
2101
+
2024
2102
 
2025
2103
  === XML
2026
2104
 
@@ -3,10 +3,20 @@ module Lutaml
3
3
  class Attribute
4
4
  attr_reader :name, :type, :options
5
5
 
6
+ ALLOWED_OPTIONS = %i[
7
+ raw
8
+ default
9
+ delegate
10
+ collection
11
+ values
12
+ ].freeze
13
+
6
14
  def initialize(name, type, options = {})
7
15
  @name = name
8
16
  @type = cast_type(type)
9
17
  @options = options
18
+ validate_options!
19
+
10
20
  @raw = !!options[:raw]
11
21
 
12
22
  if collection?
@@ -54,10 +64,6 @@ module Lutaml
54
64
  @raw
55
65
  end
56
66
 
57
- def render_default?
58
- !!@options[:render_default]
59
- end
60
-
61
67
  def default
62
68
  value = if delegate
63
69
  type.attributes[to].default
@@ -70,10 +76,6 @@ module Lutaml
70
76
  cast_value(value)
71
77
  end
72
78
 
73
- def render_nil?
74
- options.fetch(:render_nil, false)
75
- end
76
-
77
79
  def enum_values
78
80
  @options.key?(:values) ? @options[:values] : []
79
81
  end
@@ -207,6 +209,14 @@ module Lutaml
207
209
  Lutaml::Model::Type.cast(value, type)
208
210
  end
209
211
  end
212
+
213
+ private
214
+
215
+ def validate_options!
216
+ if (options = @options.keys - ALLOWED_OPTIONS).any?
217
+ raise StandardError, "Invalid options given for `#{name}` #{options}"
218
+ end
219
+ end
210
220
  end
211
221
  end
212
222
  end
@@ -13,6 +13,7 @@ module Lutaml
13
13
  name,
14
14
  to: nil,
15
15
  render_nil: false,
16
+ render_default: false,
16
17
  with: {},
17
18
  delegate: nil,
18
19
  child_mappings: nil
@@ -23,6 +24,7 @@ module Lutaml
23
24
  name,
24
25
  to: to,
25
26
  render_nil: render_nil,
27
+ render_default: render_default,
26
28
  with: with,
27
29
  delegate: delegate,
28
30
  child_mappings: child_mappings,
@@ -9,6 +9,7 @@ module Lutaml
9
9
  name,
10
10
  to:,
11
11
  render_nil: false,
12
+ render_default: false,
12
13
  with: {},
13
14
  delegate: nil,
14
15
  child_mappings: nil
@@ -17,6 +18,7 @@ module Lutaml
17
18
  name,
18
19
  to: to,
19
20
  render_nil: render_nil,
21
+ render_default: render_default,
20
22
  with: with,
21
23
  delegate: delegate,
22
24
  )
@@ -40,35 +40,30 @@ module Lutaml
40
40
  def model(klass = nil)
41
41
  if klass
42
42
  @model = klass
43
- add_order_handling_methods_to_model(klass)
43
+ add_custom_handling_methods_to_model(klass)
44
44
  else
45
45
  @model
46
46
  end
47
47
  end
48
48
 
49
- def add_order_handling_methods_to_model(klass)
50
- Utils.add_method_if_not_defined(klass, :ordered=) do |ordered|
51
- @ordered = ordered
52
- end
53
-
54
- Utils.add_method_if_not_defined(klass, :ordered?) do
55
- !!@ordered
56
- end
57
-
58
- Utils.add_method_if_not_defined(klass, :mixed=) do |mixed|
59
- @mixed = mixed
60
- end
49
+ def add_custom_handling_methods_to_model(klass)
50
+ Utils.add_boolean_accessor_if_not_defined(klass, :ordered)
51
+ Utils.add_boolean_accessor_if_not_defined(klass, :mixed)
52
+ Utils.add_accessor_if_not_defined(klass, :element_order)
61
53
 
62
- Utils.add_method_if_not_defined(klass, :mixed?) do
63
- !!@mixed
54
+ Utils.add_method_if_not_defined(klass, :using_default_for) do |attribute_name|
55
+ @using_default ||= {}
56
+ @using_default[attribute_name] = true
64
57
  end
65
58
 
66
- Utils.add_method_if_not_defined(klass, :element_order=) do |order|
67
- @element_order = order
59
+ Utils.add_method_if_not_defined(klass, :value_set_for) do |attribute_name|
60
+ @using_default ||= {}
61
+ @using_default[attribute_name] = false
68
62
  end
69
63
 
70
- Utils.add_method_if_not_defined(klass, :element_order) do
71
- @element_order
64
+ Utils.add_method_if_not_defined(klass, :using_default?) do |attribute_name|
65
+ @using_default ||= {}
66
+ !!@using_default[attribute_name]
72
67
  end
73
68
  end
74
69
 
@@ -160,6 +155,7 @@ module Lutaml
160
155
  mappings.each_with_object({}) do |rule, hash|
161
156
  name = rule.to
162
157
  next if except&.include?(name) || (only && !only.include?(name))
158
+ next if !rule.render_default? && instance.using_default?(rule.to)
163
159
 
164
160
  next handle_delegate(instance, rule, hash, format) if rule.delegate
165
161
 
@@ -224,11 +220,10 @@ module Lutaml
224
220
  klass = format == :xml ? XmlMapping : KeyValueMapping
225
221
 
226
222
  klass.new.tap do |mapping|
227
- attributes&.each do |name, attr|
223
+ attributes&.each_key do |name|
228
224
  mapping.map_element(
229
225
  name.to_s,
230
226
  to: name,
231
- render_nil: attr.render_nil?,
232
227
  )
233
228
  end
234
229
 
@@ -351,7 +346,7 @@ module Lutaml
351
346
  end
352
347
 
353
348
  defaults_used.each do |attribute_name|
354
- instance.using_default_for(attribute_name) if instance.respond_to?(:using_default_for)
349
+ instance.using_default_for(attribute_name)
355
350
  end
356
351
 
357
352
  instance
@@ -50,6 +50,34 @@ module Lutaml
50
50
  end
51
51
  end
52
52
 
53
+ def add_accessor_if_not_defined(klass, attribute)
54
+ add_getter_if_not_defined(klass, attribute)
55
+ add_setter_if_not_defined(klass, attribute)
56
+ end
57
+
58
+ def add_boolean_accessor_if_not_defined(klass, attribute)
59
+ add_boolean_getter_if_not_defined(klass, attribute)
60
+ add_setter_if_not_defined(klass, attribute)
61
+ end
62
+
63
+ def add_getter_if_not_defined(klass, attribute)
64
+ add_method_if_not_defined(klass, attribute) do
65
+ instance_variable_get(:"@__#{attribute}")
66
+ end
67
+ end
68
+
69
+ def add_boolean_getter_if_not_defined(klass, attribute)
70
+ add_method_if_not_defined(klass, "#{attribute}?") do
71
+ !!instance_variable_get(:"@__#{attribute}")
72
+ end
73
+ end
74
+
75
+ def add_setter_if_not_defined(klass, attribute)
76
+ add_method_if_not_defined(klass, "#{attribute}=") do |value|
77
+ instance_variable_set(:"@__#{attribute}", value)
78
+ end
79
+ end
80
+
53
81
  def deep_dup(hash)
54
82
  return hash if hash.nil?
55
83
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Lutaml
4
4
  module Model
5
- VERSION = "0.3.15"
5
+ VERSION = "0.3.16"
6
6
  end
7
7
  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.3.15
4
+ version: 0.3.16
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-10-26 00:00:00.000000000 Z
11
+ date: 2024-10-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor