lutaml-model 0.2.1 → 0.3.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c28f7695801483c724c6d8b03e37b1bc269eb82a506b4e363f65078142bed860
4
- data.tar.gz: feb57e7df6c86c2cc3cdaa03012045e017c557a2f957b74c639d80feb53a36fc
3
+ metadata.gz: 2b948b6c3373e3a5cbe98462e88fe5b945542d9f509b313dd21af2f333859884
4
+ data.tar.gz: 0c53660f6ff3f8ad249c3368c6c1477eb4d5ea1d426d9c4db44216efec9e5b56
5
5
  SHA512:
6
- metadata.gz: 4a9641bec82c8c12099bc5c332931aa1f52b0dd8594ebc6e43722ace015c838522e7ebc873b834e324167db151b5055bbb495461ee585f6fdcd1c400ddbe7513
7
- data.tar.gz: 88090ad9c5dc0be10531d1fc5c053db353fd5a30412279f19868b4786d046ae1f9b9f03237709c1928afd039f2b94809e137a6ad430e3fe2d04e200416cc8949
6
+ metadata.gz: 032c506ddc4f5173281092dae4828c63717454dbcdf8ed44fb30bc94482552bffbfbf830084c9ae1b832c49db802f940b81adf684ea94d684d0496bd804e5dbf
7
+ data.tar.gz: 4b75612301d6df11570f30b04ddd7800b666ae354a9c2171d553fc14cce21846795c54f88e25c4a35896ee66701b14c27fd825f9146fdd3ec469ede544405bd3
data/.gitignore CHANGED
@@ -1,3 +1,5 @@
1
+ .rubocop-https---*
2
+
1
3
  /.bundle/
2
4
  /.yardoc
3
5
  /_yardoc/
data/.rubocop.yml CHANGED
@@ -1,8 +1,15 @@
1
1
  inherit_from:
2
2
  - https://raw.githubusercontent.com/riboseinc/oss-guides/master/ci/rubocop.yml
3
+ - .rubocop_todo.yml
3
4
 
4
5
  # local repo-specific modifications
5
6
  # ...
7
+ #
8
+ require:
9
+ - rubocop-performance
10
+ - rubocop-rails
11
+ - rubocop-rake
12
+ - rubocop-rspec
6
13
 
7
14
  AllCops:
8
15
  TargetRubyVersion: 3.0
data/.rubocop_todo.yml ADDED
@@ -0,0 +1,207 @@
1
+ # This configuration was generated by
2
+ # `rubocop --auto-gen-config`
3
+ # on 2024-07-31 10:20:40 UTC using RuboCop version 1.64.1.
4
+ # The point is for the user to remove these configuration records
5
+ # one by one as the offenses are removed from the code base.
6
+ # Note that changes in the inspected code, or installation of new
7
+ # versions of RuboCop, may require this file to be generated again.
8
+
9
+ # Offense count: 1
10
+ # This cop supports safe autocorrection (--autocorrect).
11
+ # Configuration parameters: Severity, Include.
12
+ # Include: **/*.gemspec
13
+ Gemspec/RequireMFA:
14
+ Exclude:
15
+ - 'lutaml-model.gemspec'
16
+
17
+ # Offense count: 15
18
+ # This cop supports safe autocorrection (--autocorrect).
19
+ # Configuration parameters: Max, AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, AllowedPatterns.
20
+ # URISchemes: http, https
21
+ Layout/LineLength:
22
+ Exclude:
23
+ - 'lib/lutaml/model/serialize.rb'
24
+ - 'lib/lutaml/model/type.rb'
25
+ - 'lib/lutaml/model/xml_adapter.rb'
26
+ - 'lib/lutaml/model/xml_adapter/nokogiri_adapter.rb'
27
+ - 'lib/lutaml/model/xml_adapter/ox_adapter.rb'
28
+ - 'spec/lutaml/model/xml_namespace_spec.rb'
29
+
30
+ # Offense count: 20
31
+ # Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes, Max.
32
+ Metrics/AbcSize:
33
+ Exclude:
34
+ - 'lib/lutaml/model/serialize.rb'
35
+ - 'lib/lutaml/model/type.rb'
36
+ - 'lib/lutaml/model/xml_adapter.rb'
37
+ - 'lib/lutaml/model/xml_adapter/nokogiri_adapter.rb'
38
+ - 'lib/lutaml/model/xml_adapter/ox_adapter.rb'
39
+
40
+ # Offense count: 3
41
+ # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns, inherit_mode.
42
+ # AllowedMethods: refine
43
+ Metrics/BlockLength:
44
+ Max: 30
45
+
46
+ # Offense count: 17
47
+ # Configuration parameters: AllowedMethods, AllowedPatterns, Max.
48
+ Metrics/CyclomaticComplexity:
49
+ Exclude:
50
+ - 'lib/lutaml/model/serialize.rb'
51
+ - 'lib/lutaml/model/type.rb'
52
+ - 'lib/lutaml/model/xml_adapter.rb'
53
+ - 'lib/lutaml/model/xml_adapter/nokogiri_adapter.rb'
54
+ - 'lib/lutaml/model/xml_adapter/ox_adapter.rb'
55
+
56
+ # Offense count: 24
57
+ # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
58
+ Metrics/MethodLength:
59
+ Max: 42
60
+
61
+ # Offense count: 3
62
+ # Configuration parameters: CountKeywordArgs, MaxOptionalParameters.
63
+ Metrics/ParameterLists:
64
+ Max: 9
65
+
66
+ # Offense count: 16
67
+ # Configuration parameters: AllowedMethods, AllowedPatterns, Max.
68
+ Metrics/PerceivedComplexity:
69
+ Exclude:
70
+ - 'lib/lutaml/model/serialize.rb'
71
+ - 'lib/lutaml/model/type.rb'
72
+ - 'lib/lutaml/model/xml_adapter.rb'
73
+ - 'lib/lutaml/model/xml_adapter/nokogiri_adapter.rb'
74
+ - 'lib/lutaml/model/xml_adapter/ox_adapter.rb'
75
+
76
+ # Offense count: 2
77
+ # This cop supports unsafe autocorrection (--autocorrect-all).
78
+ RSpec/BeEq:
79
+ Exclude:
80
+ - 'spec/lutaml/model/collection_spec.rb'
81
+ - 'spec/lutaml/model/simple_model_spec.rb'
82
+
83
+ # Offense count: 1
84
+ # This cop supports safe autocorrection (--autocorrect).
85
+ # Configuration parameters: EnforcedStyle.
86
+ # SupportedStyles: be, be_nil
87
+ RSpec/BeNil:
88
+ Exclude:
89
+ - 'spec/lutaml/model_spec.rb'
90
+
91
+ # Offense count: 6
92
+ # Configuration parameters: Prefixes, AllowedPatterns.
93
+ # Prefixes: when, with, without
94
+ RSpec/ContextWording:
95
+ Exclude:
96
+ - 'spec/lutaml/model/xml_adapter/nokogiri_adapter_spec.rb'
97
+ - 'spec/lutaml/model/xml_adapter/oga_adapter_spec.rb'
98
+ - 'spec/lutaml/model/xml_adapter/ox_adapter_spec.rb'
99
+
100
+ # Offense count: 18
101
+ # This cop supports unsafe autocorrection (--autocorrect-all).
102
+ # Configuration parameters: SkipBlocks, EnforcedStyle, OnlyStaticConstants.
103
+ # SupportedStyles: described_class, explicit
104
+ RSpec/DescribedClass:
105
+ Exclude:
106
+ - 'spec/address_spec.rb'
107
+ - 'spec/lutaml/model/custom_serialization_spec.rb'
108
+ - 'spec/lutaml/model/defaults_spec.rb'
109
+ - 'spec/lutaml/model/render_nil_spec.rb'
110
+ - 'spec/person_spec.rb'
111
+
112
+ # Offense count: 60
113
+ # Configuration parameters: CountAsOne.
114
+ RSpec/ExampleLength:
115
+ Max: 36
116
+
117
+ # Offense count: 2
118
+ # Configuration parameters: Max, AllowedIdentifiers, AllowedPatterns.
119
+ RSpec/IndexedLet:
120
+ Exclude:
121
+ - 'spec/address_spec.rb'
122
+
123
+ # Offense count: 3
124
+ # This cop supports safe autocorrection (--autocorrect).
125
+ # Configuration parameters: AutoCorrect.
126
+ RSpec/LetBeforeExamples:
127
+ Exclude:
128
+ - 'spec/lutaml/model/defaults_spec.rb'
129
+ - 'spec/person_spec.rb'
130
+
131
+ # Offense count: 4
132
+ RSpec/MultipleDescribes:
133
+ Exclude:
134
+ - 'spec/lutaml/model/json_adapter_spec.rb'
135
+ - 'spec/lutaml/model/toml_adapter_spec.rb'
136
+ - 'spec/lutaml/model/xml_adapter_spec.rb'
137
+ - 'spec/lutaml/model/xml_namespace_spec.rb'
138
+
139
+ # Offense count: 54
140
+ RSpec/MultipleExpectations:
141
+ Max: 15
142
+
143
+ # Offense count: 1
144
+ # Configuration parameters: AllowSubject.
145
+ RSpec/MultipleMemoizedHelpers:
146
+ Max: 9
147
+
148
+ # Offense count: 3
149
+ RSpec/PendingWithoutReason:
150
+ Exclude:
151
+ - 'spec/lutaml/model/xml_adapter/oga_adapter_spec.rb'
152
+ - 'spec/lutaml/model/xml_adapter_spec.rb'
153
+ - 'spec/lutaml/model/xml_namespace_spec.rb'
154
+
155
+ # Offense count: 3
156
+ # This cop supports safe autocorrection (--autocorrect).
157
+ # Configuration parameters: AutoCorrect.
158
+ RSpec/ScatteredLet:
159
+ Exclude:
160
+ - 'spec/lutaml/model/defaults_spec.rb'
161
+ - 'spec/person_spec.rb'
162
+
163
+ # Offense count: 5
164
+ # Configuration parameters: Include, CustomTransform, IgnoreMethods, IgnoreMetadata.
165
+ # Include: **/*_spec.rb
166
+ RSpec/SpecFilePathFormat:
167
+ Exclude:
168
+ - 'spec/lutaml/model/collection_spec.rb'
169
+ - 'spec/lutaml/model/xml_adapter/nokogiri_adapter_spec.rb'
170
+ - 'spec/lutaml/model/xml_adapter/oga_adapter_spec.rb'
171
+ - 'spec/lutaml/model/xml_adapter/ox_adapter_spec.rb'
172
+ - 'spec/lutaml/model/yaml_adapter_spec.rb'
173
+
174
+ # Offense count: 2
175
+ # This cop supports unsafe autocorrection (--autocorrect-all).
176
+ # Configuration parameters: Whitelist, AllowedMethods, AllowedReceivers.
177
+ # Whitelist: find_by_sql, find_by_token_for
178
+ # AllowedMethods: find_by_sql, find_by_token_for
179
+ # AllowedReceivers: Gem::Specification, page
180
+ Rails/DynamicFindBy:
181
+ Exclude:
182
+ - 'lib/lutaml/model/xml_adapter/nokogiri_adapter.rb'
183
+ - 'lib/lutaml/model/xml_adapter/ox_adapter.rb'
184
+
185
+ # Offense count: 1
186
+ # This cop supports unsafe autocorrection (--autocorrect-all).
187
+ Rails/NegateInclude:
188
+ Exclude:
189
+ - 'lib/lutaml/model/serialize.rb'
190
+
191
+ # Offense count: 2
192
+ # This cop supports safe autocorrection (--autocorrect).
193
+ # Configuration parameters: NotNilAndNotEmpty, NotBlank, UnlessBlank.
194
+ Rails/Present:
195
+ Exclude:
196
+ - 'lib/lutaml/model/serialize.rb'
197
+ - 'lib/lutaml/model/xml_namespace.rb'
198
+
199
+ # Offense count: 6
200
+ # This cop supports unsafe autocorrection (--autocorrect-all).
201
+ # Configuration parameters: EnforcedStyle.
202
+ # SupportedStyles: strict, flexible
203
+ Rails/TimeZone:
204
+ Exclude:
205
+ - 'lib/lutaml/model/type.rb'
206
+ - 'lib/lutaml/model/type/time_without_date.rb'
207
+ - 'spec/person_spec.rb'
data/Gemfile CHANGED
@@ -23,9 +23,13 @@ gem "ox"
23
23
 
24
24
  gem "pry"
25
25
 
26
- gem "rubocop-performance"
26
+ gem "rubocop-performance", require: false
27
27
 
28
- gem "rubocop-rails"
28
+ gem "rubocop-rails", require: false
29
+
30
+ gem "rubocop-rake", require: false
31
+
32
+ gem "rubocop-rspec", require: false
29
33
 
30
34
  gem "tomlib"
31
35
 
data/README.adoc CHANGED
@@ -105,6 +105,8 @@ class Example < Lutaml::Model::Serializable
105
105
  end
106
106
  ----
107
107
 
108
+ NOTE: If root is not given then the class name will be used as the root.
109
+
108
110
  === Key Value Data Models: JSON, YAML, TOML
109
111
 
110
112
  Define key-value data models like JSON, YAML, and TOML using the `map` method.
@@ -294,16 +296,31 @@ end
294
296
 
295
297
  === XML Namespace on Attribute
296
298
 
299
+ If the namespace is defined on an attribute then that will be given priority over the one defined in the class. In the example below `glz` will be used for `Glaze` if it is added inside the `Ceramic` class, and `glaze` will be used otherwise.
300
+
297
301
  [source,ruby]
298
302
  ----
303
+ class Glaze < Lutaml::Model::Serializable
304
+ attribute :color, Lutaml::Model::Type::String
305
+ attribute :temperature, Lutaml::Model::Type::Integer
306
+
307
+ xml do
308
+ root 'Glaze'
309
+ namespace 'http://example.com/old_glaze', 'glaze'
310
+
311
+ map_element 'color', to: :color
312
+ map_element 'temperature', to: :temperature
313
+ end
314
+ end
315
+
299
316
  class Ceramic < Lutaml::Model::Serializable
300
317
  attribute :type, Lutaml::Model::Type::String
301
- attribute :glaze, Lutaml::Model::Type::String
318
+ attribute :glaze, Glaze
302
319
 
303
320
  xml do
304
321
  root 'Ceramic'
305
322
  map_element 'Type', to: :type
306
- map_element 'Glaze', to: :glaze
323
+ map_element 'Glaze', to: :glaze, namespace: 'http://example.com/glaze', prefix: "glz"
307
324
  map_attribute 'xmlns', to: :namespace, namespace: 'http://example.com/ceramic'
308
325
  end
309
326
  end
@@ -326,6 +343,60 @@ class Ceramic < Lutaml::Model::Serializable
326
343
  end
327
344
  ----
328
345
 
346
+ == Using XML `mixed` option
347
+
348
+ In XML there can be some tags that containg content mixed with other tags for example `<description><p>My name is <bold>John Doe</bold>, and I'm <i>28</i> years old</p></description>`
349
+
350
+ To map this to Lutaml::Model we can use the mixed option when defining the model or when referencing it.
351
+
352
+ === Adding mixed option when defining a Model
353
+
354
+ This will always treat the content of `<p>` tag as mixed content.
355
+
356
+ [source,ruby]
357
+ ----
358
+ class Paragraph < Lutaml::Model::Serializable
359
+ attribute :bold, Lutaml::Model::Type::String
360
+ attribute :italic, Lutaml::Model::Type::String
361
+
362
+ xml do
363
+ root 'p', mixed: true
364
+
365
+ map_element 'bold', to: :bold
366
+ map_element 'i', to: :italic
367
+ end
368
+ end
369
+ ----
370
+
371
+ === Adding mixed option when referencing a Model
372
+
373
+ This will only treat the content of `<p>` tag as mixed content if the `mixed: true` is added when referencing it.
374
+
375
+ [source,ruby]
376
+ ----
377
+ class Paragraph < Lutaml::Model::Serializable
378
+ attribute :bold, Lutaml::Model::Type::String
379
+ attribute :italic, Lutaml::Model::Type::String
380
+
381
+ xml do
382
+ root 'p'
383
+
384
+ map_element 'bold', to: :bold
385
+ map_element 'i', to: :italic
386
+ end
387
+ end
388
+
389
+ class Description < Lutaml::Model::Serializable
390
+ attribute :paragraph, Paragraph
391
+
392
+ xml do
393
+ root 'description'
394
+
395
+ map_element 'p', to: :paragraph, mixed: true
396
+ end
397
+ end
398
+ ----
399
+
329
400
  == Adapters
330
401
 
331
402
  Lutaml::Model uses an adapter pattern to support multiple libraries for each serialization format.
@@ -377,4 +448,4 @@ end
377
448
 
378
449
  This project is licensed under the BSD 2-clause License - see the LICENSE file for details.
379
450
 
380
- This project is maintained by Ribose.
451
+ This project is maintained by Ribose.
@@ -8,6 +8,10 @@ module Lutaml
8
8
  @name = name
9
9
  @type = type
10
10
  @options = options
11
+
12
+ if collection? && !options[:default]
13
+ @options[:default] = -> { [] }
14
+ end
11
15
  end
12
16
 
13
17
  def collection?
@@ -0,0 +1,42 @@
1
+ # lib/lutaml/model/type.rb
2
+
3
+ module Lutaml
4
+ module Model
5
+ class MappingHash < Hash
6
+ attr_accessor :ordered
7
+
8
+ def initialize
9
+ @ordered = false
10
+ @item_order = []
11
+
12
+ super
13
+ end
14
+
15
+ def item_order
16
+ @item_order&.map { |key| normalize(key) } || keys
17
+ end
18
+
19
+ def item_order=(order)
20
+ raise "`item order` must be an array" unless order.is_a?(Array)
21
+
22
+ @item_order = order
23
+ end
24
+
25
+ def ordered?
26
+ @ordered
27
+ end
28
+
29
+ private
30
+
31
+ def normalize(key)
32
+ if self[key.to_s]
33
+ key.to_s
34
+ elsif self[key.to_sym]
35
+ key.to_sym
36
+ else
37
+ key
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -2,14 +2,29 @@
2
2
  module Lutaml
3
3
  module Model
4
4
  class MappingRule
5
- attr_reader :name, :to, :render_nil, :custom_methods, :delegate
5
+ attr_reader :name,
6
+ :to,
7
+ :render_nil,
8
+ :custom_methods,
9
+ :delegate,
10
+ :mixed_content
6
11
 
7
- def initialize(name, to:, render_nil: false, with: {}, delegate: nil)
12
+ def initialize(
13
+ name,
14
+ to:,
15
+ render_nil: false,
16
+ with: {},
17
+ delegate: nil,
18
+ mixed_content: false,
19
+ namespace_set: false
20
+ )
8
21
  @name = name
9
22
  @to = to
10
23
  @render_nil = render_nil
11
24
  @custom_methods = with
12
25
  @delegate = delegate
26
+ @mixed_content = mixed_content
27
+ @namespace_set = namespace_set
13
28
  end
14
29
 
15
30
  alias from name
@@ -38,6 +53,10 @@ module Lutaml
38
53
  doc[name.to_s]
39
54
  end
40
55
  end
56
+
57
+ def namespace_set?
58
+ @namespace_set
59
+ end
41
60
  end
42
61
  end
43
62
  end