lutaml-model 0.8.28 → 0.8.29

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: b364f3d15a4c9fc529d85154e1e4789997432f557be698bfef559e3dc1139163
4
- data.tar.gz: 3fe6af19792fc59b5800d0078e34171dd9b5d4c4009922e43a8eb0050ad8308c
3
+ metadata.gz: 9bf8f1fa19aff84c4b18067af1d357836567e7911c1217400fb1ae02afaaacff
4
+ data.tar.gz: 338d5c09177e3369a1910310523c2f3db651c6c157a225d1c2e46ca1cb7fac58
5
5
  SHA512:
6
- metadata.gz: 7b3ebf674d7f7d306caea42542b54250dcd7ebbffc23186e2e8aa2b932d040e7dcdf4f74f41b1a9b66f089661eacd3eb8cf0676c8728b471f14e5c403175f2d4
7
- data.tar.gz: e38d81dc78936d9e24d0f389134bca507c7a77d338196663ef10d1986bc3165da3ae7c88043ef0fe5c04189aace3f846034ed5a03f3463d7dfbf48267ab42fa6
6
+ metadata.gz: e18027c4914b6d7ad596612b46a1eb3e76b321c3f2d0fcc5677781ddff7da466f57b3923dff8059174dedb8e50be24a11e798b848c35b63ded06ab67d94718be
7
+ data.tar.gz: 4c828806bd1de1f35b85ced4106048d0a22b337cf970feede46b40c7d7b3ee87df1782f27ada7e76ed694877364ce982901b31c1b78245ef256169173915313f
@@ -57,23 +57,24 @@ model_class: nil)
57
57
  return nil if value.nil?
58
58
  return nil if Lutaml::Model::Utils.uninitialized?(value)
59
59
 
60
- # Compiled serialize plan (TODO.perf/07): builtin scalars whose
61
- # type registers no custom to_<format> serializer serialize as the
62
- # value itselfType::Value#to_<format>'s default without the
63
- # wrap-allocate-cast ceremony per field. Computed once per rule.
64
- if (fast = serialize_plan(rule)) && value.instance_of?(fast)
60
+ # Compiled serialize plan (TODO.perf/07): the rule-invariant
61
+ # probes identity-fast builtin scalars, Reference, union,
62
+ # nested-model classificationresolve once per rule; the
63
+ # per-field hash lookups dominated primitive-heavy docs.
64
+ plan = serialize_plan(rule)
65
+ if (fast = plan[:identity_type]) && value.instance_of?(fast)
65
66
  return value
66
67
  end
67
68
 
68
69
  # Check for Reference type first - even if value is a Serializable,
69
70
  # it should be serialized as a key, not as a nested model
70
- if reference_type?(rule)
71
+ if plan[:reference]
71
72
  return serialize_reference(value, rule)
72
73
  end
73
74
 
74
- if Lutaml::Model::Type::Union.rule?(rule)
75
+ if plan[:union]
75
76
  serialize_union(value, options)
76
- elsif nested_model?(rule)
77
+ elsif plan[:nested]
77
78
  serialize_nested_model(value, rule, options)
78
79
  else
79
80
  serialize_primitive(value, rule)
@@ -162,18 +163,45 @@ model_class: nil)
162
163
  # Per-rule serialize plan: the type class for builtin scalars with
163
164
  # no custom to_<format> serializer (identity serialization), nil
164
165
  # otherwise. Memoized per [rule].
166
+ # Rule-invariant resolution for Transformation#serialize_value,
167
+ # memoized here (Transformation freezes itself after compile;
168
+ # the ValueSerializer shares its model_class/register_id).
169
+ def serialize_value_plan(rule)
170
+ @serialize_value_plans ||= {}
171
+ @serialize_value_plans[rule] ||= begin
172
+ attr = model_class.attributes(register_id)&.[](rule.attribute_name)
173
+ attr ||= model_class.attributes&.[](rule.attribute_name)
174
+ {
175
+ attr: attr,
176
+ reference: attr && attr.unresolved_type == Lutaml::Model::Type::Reference,
177
+ nested: rule.attribute_type.is_a?(Class) &&
178
+ rule.attribute_type < Lutaml::Model::Serialize,
179
+ }
180
+ end
181
+ end
182
+
165
183
  def serialize_plan(rule)
166
184
  @serialize_plans ||= {}
167
- @serialize_plans[rule] ||= begin
168
- type = rule.attribute_type
169
- if type.is_a?(::Class) && type < ::Lutaml::Model::Type::Value
170
- serializer = ::Lutaml::Model::Type::Value
171
- .format_type_serializer_for(@format, type)
172
- has_custom_to = serializer && serializer[:to]
173
- has_custom_from = ::Lutaml::Model::Attribute.custom_from_probe?(type)
174
- type unless has_custom_to || has_custom_from
175
- end
176
- end
185
+ @serialize_plans[rule] ||= {
186
+ identity_type: identity_fast_type(rule),
187
+ reference: reference_type?(rule),
188
+ union: ::Lutaml::Model::Type::Union.rule?(rule),
189
+ nested: nested_model?(rule),
190
+ }
191
+ end
192
+
193
+ # Builtin scalars whose type registers no custom to_<format>
194
+ # serializer serialize as the value itself — Type::Value#to_<format>'s
195
+ # default — without the wrap-allocate-cast ceremony per field.
196
+ def identity_fast_type(rule)
197
+ type = rule.attribute_type
198
+ return nil unless type.is_a?(::Class) && type < ::Lutaml::Model::Type::Value
199
+
200
+ serializer = ::Lutaml::Model::Type::Value
201
+ .format_type_serializer_for(@format, type)
202
+ has_custom_to = serializer && serializer[:to]
203
+ has_custom_from = ::Lutaml::Model::Attribute.custom_from_probe?(type)
204
+ type unless has_custom_to || has_custom_from
177
205
  end
178
206
 
179
207
  private
@@ -1069,19 +1069,20 @@ child_mappings, options)
1069
1069
  return nil if value.nil?
1070
1070
  return nil if Lutaml::Model::Utils.uninitialized?(value)
1071
1071
 
1072
- # For Reference types, use attribute's serialize method which handles reference_key extraction
1073
- # Check the attribute's unresolved_type to match the condition in Attribute#serialize
1074
- # Try to get attribute from model_class (with register first, then without)
1075
- attr = model_class.attributes(register_id)&.[](rule.attribute_name)
1076
- attr ||= model_class.attributes&.[](rule.attribute_name)
1077
-
1078
- if attr && attr.unresolved_type == Lutaml::Model::Type::Reference
1079
- return attr.serialize(value, format, register_id, {})
1072
+ # Rule-invariant resolution (attribute lookup, Reference probe,
1073
+ # nested-type class) is compiled once per rule the per-value
1074
+ # hash lookups dominated primitive-heavy serialization.
1075
+ # Transformation freezes itself after compile; the plan cache
1076
+ # lives on the ValueSerializer (same model_class/register_id).
1077
+ plan = value_serializer.serialize_value_plan(rule)
1078
+
1079
+ if plan[:reference]
1080
+ return plan[:attr].serialize(value, format, register_id, {})
1080
1081
  end
1081
1082
 
1082
1083
  # Validate that value is an instance of the expected Serializable type
1083
1084
  # When attribute_type is a Serializable class, value must be an instance of that class
1084
- if rule.attribute_type.is_a?(Class) && rule.attribute_type < Lutaml::Model::Serialize
1085
+ if plan[:nested]
1085
1086
  unless value.is_a?(rule.attribute_type)
1086
1087
  msg = "attribute '#{rule.attribute_name}' value is a '#{value.class}' but should be a '#{rule.attribute_type}'"
1087
1088
  raise Lutaml::Model::IncorrectModelError, msg
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Lutaml
4
4
  module Model
5
- VERSION = "0.8.28"
5
+ VERSION = "0.8.29"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lutaml-model
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.28
4
+ version: 0.8.29
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.