lutaml-model 0.8.37 → 0.8.38
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 +4 -4
- data/bench/gate_config.rb +5 -4
- data/lib/compat/opal/lutaml_model_boot.rb +1 -0
- data/lib/lutaml/key_value/transform.rb +52 -5
- data/lib/lutaml/key_value/transformation.rb +10 -2
- data/lib/lutaml/model/attribute.rb +5 -1
- data/lib/lutaml/model/format_registry.rb +3 -1
- data/lib/lutaml/model/mapping/mapping_rule.rb +39 -11
- data/lib/lutaml/model/serialize/attribute_definition.rb +140 -65
- data/lib/lutaml/model/serialize/deserialization_context.rb +1 -0
- data/lib/lutaml/model/serialize.rb +54 -15
- data/lib/lutaml/model/services/transformer.rb +30 -11
- data/lib/lutaml/model/version.rb +1 -1
- data/lib/lutaml/xml/format.rb +1 -0
- data/lib/lutaml/xml/html_entities.rb +290 -0
- data/lib/lutaml/xml/mapping.rb +19 -0
- data/lib/lutaml/xml/model_transform.rb +174 -53
- data/lib/lutaml/xml/parse_session.rb +24 -11
- data/lib/lutaml/yaml/format.rb +1 -0
- data/spec/lutaml/model/custom_method_context_spec.rb +62 -0
- data/spec/lutaml/model/yaml_stream_spec.rb +70 -0
- data/spec/lutaml/xml/html_entities_spec.rb +45 -0
- metadata +5 -1
|
@@ -2,8 +2,8 @@ module Lutaml
|
|
|
2
2
|
module Model
|
|
3
3
|
class Transformer
|
|
4
4
|
class << self
|
|
5
|
-
def call(value, rule, attribute, format: nil)
|
|
6
|
-
new(rule, attribute, format).call(value)
|
|
5
|
+
def call(value, rule, attribute, format: nil, context: nil)
|
|
6
|
+
new(rule, attribute, format, context).call(value)
|
|
7
7
|
end
|
|
8
8
|
|
|
9
9
|
private
|
|
@@ -15,7 +15,7 @@ module Lutaml
|
|
|
15
15
|
transform.is_a?(::Hash) ? transform[direction] : transform
|
|
16
16
|
end
|
|
17
17
|
|
|
18
|
-
def apply_static(value, sources, direction, format)
|
|
18
|
+
def apply_static(value, sources, direction, format, context = nil)
|
|
19
19
|
methods = sources.filter_map do |obj|
|
|
20
20
|
get_transform_static(obj, direction)
|
|
21
21
|
end
|
|
@@ -34,16 +34,23 @@ module Lutaml
|
|
|
34
34
|
tc.public_send(apply_direction, v, format)
|
|
35
35
|
end
|
|
36
36
|
|
|
37
|
-
methods.reduce(result)
|
|
37
|
+
methods.reduce(result) do |tv, m|
|
|
38
|
+
if m.arity == 2
|
|
39
|
+
m.call(tv, context)
|
|
40
|
+
else
|
|
41
|
+
m.call(tv)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
38
44
|
end
|
|
39
45
|
end
|
|
40
46
|
|
|
41
|
-
attr_reader :rule, :attribute, :format
|
|
47
|
+
attr_reader :rule, :attribute, :format, :context
|
|
42
48
|
|
|
43
|
-
def initialize(rule, attribute, format = nil)
|
|
49
|
+
def initialize(rule, attribute, format = nil, context = nil)
|
|
44
50
|
@rule = rule
|
|
45
51
|
@attribute = attribute
|
|
46
52
|
@format = format
|
|
53
|
+
@context = context
|
|
47
54
|
end
|
|
48
55
|
|
|
49
56
|
def call(value)
|
|
@@ -61,7 +68,19 @@ module Lutaml
|
|
|
61
68
|
end
|
|
62
69
|
|
|
63
70
|
methods.reduce(result) do |transformed_value, method|
|
|
64
|
-
method
|
|
71
|
+
invoke_transform(method, transformed_value)
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# lutaml-model#550: `with:` custom methods opt into the options
|
|
76
|
+
# passed to `from_*` / `to_*` by declaring a second parameter
|
|
77
|
+
# (exact arity 2); one-parameter methods keep the historical
|
|
78
|
+
# single-argument call.
|
|
79
|
+
def invoke_transform(method, value)
|
|
80
|
+
if method.arity == 2
|
|
81
|
+
method.call(value, context)
|
|
82
|
+
else
|
|
83
|
+
method.call(value)
|
|
65
84
|
end
|
|
66
85
|
end
|
|
67
86
|
|
|
@@ -87,8 +106,8 @@ module Lutaml
|
|
|
87
106
|
|
|
88
107
|
class ImportTransformer < Transformer
|
|
89
108
|
class << self
|
|
90
|
-
def call(value, rule, attribute, format: nil)
|
|
91
|
-
apply_static(value, [rule, attribute], :import, format)
|
|
109
|
+
def call(value, rule, attribute, format: nil, context: nil)
|
|
110
|
+
apply_static(value, [rule, attribute], :import, format, context)
|
|
92
111
|
end
|
|
93
112
|
end
|
|
94
113
|
|
|
@@ -103,8 +122,8 @@ module Lutaml
|
|
|
103
122
|
|
|
104
123
|
class ExportTransformer < Transformer
|
|
105
124
|
class << self
|
|
106
|
-
def call(value, rule, attribute, format: nil)
|
|
107
|
-
apply_static(value, [attribute, rule], :export, format)
|
|
125
|
+
def call(value, rule, attribute, format: nil, context: nil)
|
|
126
|
+
apply_static(value, [attribute, rule], :export, format, context)
|
|
108
127
|
end
|
|
109
128
|
end
|
|
110
129
|
|
data/lib/lutaml/model/version.rb
CHANGED
data/lib/lutaml/xml/format.rb
CHANGED
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# lutaml-model#154: HTML 4.01 named entity table (plus apos) for opt-in
|
|
4
|
+
# decoding of HTML entities in XML text (MathML and friends rely on
|
|
5
|
+
# them although XML itself defines none beyond the predefined five).
|
|
6
|
+
|
|
7
|
+
module Lutaml
|
|
8
|
+
module Xml
|
|
9
|
+
module HtmlEntities
|
|
10
|
+
# The table is the data: a gem dependency or data file for a static
|
|
11
|
+
# W3C list would cost more than the frozen literal itself.
|
|
12
|
+
# The table is the data: a gem dependency or data file for a static
|
|
13
|
+
# W3C list would cost more than the frozen literal itself.
|
|
14
|
+
NAMED_TO_CODEPOINT = { # rubocop:disable Metrics/CollectionLiteralLength
|
|
15
|
+
"AElig" => 198,
|
|
16
|
+
"Aacute" => 193,
|
|
17
|
+
"Acirc" => 194,
|
|
18
|
+
"Agrave" => 192,
|
|
19
|
+
"Alpha" => 913,
|
|
20
|
+
"Aring" => 197,
|
|
21
|
+
"Atilde" => 195,
|
|
22
|
+
"Auml" => 196,
|
|
23
|
+
"Beta" => 914,
|
|
24
|
+
"Ccedil" => 199,
|
|
25
|
+
"Chi" => 935,
|
|
26
|
+
"Dagger" => 8225,
|
|
27
|
+
"Delta" => 916,
|
|
28
|
+
"ETH" => 208,
|
|
29
|
+
"Eacute" => 201,
|
|
30
|
+
"Ecirc" => 202,
|
|
31
|
+
"Egrave" => 200,
|
|
32
|
+
"Epsilon" => 917,
|
|
33
|
+
"Eta" => 919,
|
|
34
|
+
"Euml" => 203,
|
|
35
|
+
"Gamma" => 915,
|
|
36
|
+
"Iacute" => 205,
|
|
37
|
+
"Icirc" => 206,
|
|
38
|
+
"Igrave" => 204,
|
|
39
|
+
"Iota" => 921,
|
|
40
|
+
"Iuml" => 207,
|
|
41
|
+
"Kappa" => 922,
|
|
42
|
+
"Lambda" => 923,
|
|
43
|
+
"Mu" => 924,
|
|
44
|
+
"Ntilde" => 209,
|
|
45
|
+
"Nu" => 925,
|
|
46
|
+
"OElig" => 338,
|
|
47
|
+
"Oacute" => 211,
|
|
48
|
+
"Ocirc" => 212,
|
|
49
|
+
"Ograve" => 210,
|
|
50
|
+
"Omega" => 937,
|
|
51
|
+
"Omicron" => 927,
|
|
52
|
+
"Oslash" => 216,
|
|
53
|
+
"Otilde" => 213,
|
|
54
|
+
"Ouml" => 214,
|
|
55
|
+
"Phi" => 934,
|
|
56
|
+
"Pi" => 928,
|
|
57
|
+
"Prime" => 8243,
|
|
58
|
+
"Psi" => 936,
|
|
59
|
+
"Rho" => 929,
|
|
60
|
+
"Scaron" => 352,
|
|
61
|
+
"Sigma" => 931,
|
|
62
|
+
"THORN" => 222,
|
|
63
|
+
"Tau" => 932,
|
|
64
|
+
"Theta" => 920,
|
|
65
|
+
"Uacute" => 218,
|
|
66
|
+
"Ucirc" => 219,
|
|
67
|
+
"Ugrave" => 217,
|
|
68
|
+
"Upsilon" => 933,
|
|
69
|
+
"Uuml" => 220,
|
|
70
|
+
"Xi" => 926,
|
|
71
|
+
"Yacute" => 221,
|
|
72
|
+
"Yuml" => 376,
|
|
73
|
+
"Zeta" => 918,
|
|
74
|
+
"aacute" => 225,
|
|
75
|
+
"acirc" => 226,
|
|
76
|
+
"acute" => 180,
|
|
77
|
+
"aelig" => 230,
|
|
78
|
+
"agrave" => 224,
|
|
79
|
+
"alefsym" => 8501,
|
|
80
|
+
"alpha" => 945,
|
|
81
|
+
"amp" => 38,
|
|
82
|
+
"and" => 8743,
|
|
83
|
+
"ang" => 8736,
|
|
84
|
+
"apos" => 39,
|
|
85
|
+
"aring" => 229,
|
|
86
|
+
"asymp" => 8776,
|
|
87
|
+
"atilde" => 227,
|
|
88
|
+
"auml" => 228,
|
|
89
|
+
"bdquo" => 8222,
|
|
90
|
+
"beta" => 946,
|
|
91
|
+
"brvbar" => 166,
|
|
92
|
+
"bull" => 8226,
|
|
93
|
+
"cap" => 8745,
|
|
94
|
+
"ccedil" => 231,
|
|
95
|
+
"cedil" => 184,
|
|
96
|
+
"cent" => 162,
|
|
97
|
+
"chi" => 967,
|
|
98
|
+
"circ" => 710,
|
|
99
|
+
"clubs" => 9827,
|
|
100
|
+
"cong" => 8773,
|
|
101
|
+
"copy" => 169,
|
|
102
|
+
"crarr" => 8629,
|
|
103
|
+
"cup" => 8746,
|
|
104
|
+
"curren" => 164,
|
|
105
|
+
"dArr" => 8659,
|
|
106
|
+
"dagger" => 8224,
|
|
107
|
+
"darr" => 8595,
|
|
108
|
+
"deg" => 176,
|
|
109
|
+
"delta" => 948,
|
|
110
|
+
"diams" => 9830,
|
|
111
|
+
"divide" => 247,
|
|
112
|
+
"eacute" => 233,
|
|
113
|
+
"ecirc" => 234,
|
|
114
|
+
"egrave" => 232,
|
|
115
|
+
"empty" => 8709,
|
|
116
|
+
"emsp" => 8195,
|
|
117
|
+
"ensp" => 8194,
|
|
118
|
+
"epsilon" => 949,
|
|
119
|
+
"equiv" => 8801,
|
|
120
|
+
"eta" => 951,
|
|
121
|
+
"eth" => 240,
|
|
122
|
+
"euml" => 235,
|
|
123
|
+
"euro" => 8364,
|
|
124
|
+
"exist" => 8707,
|
|
125
|
+
"fnof" => 402,
|
|
126
|
+
"forall" => 8704,
|
|
127
|
+
"frac12" => 189,
|
|
128
|
+
"frac14" => 188,
|
|
129
|
+
"frac34" => 190,
|
|
130
|
+
"frasl" => 8260,
|
|
131
|
+
"gamma" => 947,
|
|
132
|
+
"ge" => 8805,
|
|
133
|
+
"gt" => 62,
|
|
134
|
+
"hArr" => 8660,
|
|
135
|
+
"harr" => 8596,
|
|
136
|
+
"hearts" => 9829,
|
|
137
|
+
"hellip" => 8230,
|
|
138
|
+
"iacute" => 237,
|
|
139
|
+
"icirc" => 238,
|
|
140
|
+
"iexcl" => 161,
|
|
141
|
+
"igrave" => 236,
|
|
142
|
+
"image" => 8465,
|
|
143
|
+
"infin" => 8734,
|
|
144
|
+
"int" => 8747,
|
|
145
|
+
"iota" => 953,
|
|
146
|
+
"iquest" => 191,
|
|
147
|
+
"isin" => 8712,
|
|
148
|
+
"iuml" => 239,
|
|
149
|
+
"kappa" => 954,
|
|
150
|
+
"lArr" => 8656,
|
|
151
|
+
"lambda" => 955,
|
|
152
|
+
"lang" => 9001,
|
|
153
|
+
"laquo" => 171,
|
|
154
|
+
"larr" => 8592,
|
|
155
|
+
"lceil" => 8968,
|
|
156
|
+
"ldquo" => 8220,
|
|
157
|
+
"le" => 8804,
|
|
158
|
+
"lfloor" => 8970,
|
|
159
|
+
"lowast" => 8727,
|
|
160
|
+
"loz" => 9674,
|
|
161
|
+
"lrm" => 8206,
|
|
162
|
+
"lsaquo" => 8249,
|
|
163
|
+
"lsquo" => 8216,
|
|
164
|
+
"lt" => 60,
|
|
165
|
+
"macr" => 175,
|
|
166
|
+
"mdash" => 8212,
|
|
167
|
+
"micro" => 181,
|
|
168
|
+
"middot" => 183,
|
|
169
|
+
"minus" => 8722,
|
|
170
|
+
"mu" => 956,
|
|
171
|
+
"nabla" => 8711,
|
|
172
|
+
"nbsp" => 160,
|
|
173
|
+
"ndash" => 8211,
|
|
174
|
+
"ne" => 8800,
|
|
175
|
+
"ni" => 8715,
|
|
176
|
+
"not" => 172,
|
|
177
|
+
"notin" => 8713,
|
|
178
|
+
"nsub" => 8836,
|
|
179
|
+
"ntilde" => 241,
|
|
180
|
+
"nu" => 957,
|
|
181
|
+
"oacute" => 243,
|
|
182
|
+
"ocirc" => 244,
|
|
183
|
+
"oelig" => 339,
|
|
184
|
+
"ograve" => 242,
|
|
185
|
+
"oline" => 8254,
|
|
186
|
+
"omega" => 969,
|
|
187
|
+
"omicron" => 959,
|
|
188
|
+
"oplus" => 8853,
|
|
189
|
+
"or" => 8744,
|
|
190
|
+
"ordf" => 170,
|
|
191
|
+
"ordm" => 186,
|
|
192
|
+
"oslash" => 248,
|
|
193
|
+
"otilde" => 245,
|
|
194
|
+
"otimes" => 8855,
|
|
195
|
+
"ouml" => 246,
|
|
196
|
+
"para" => 182,
|
|
197
|
+
"part" => 8706,
|
|
198
|
+
"permil" => 8240,
|
|
199
|
+
"perp" => 8869,
|
|
200
|
+
"phi" => 966,
|
|
201
|
+
"pi" => 960,
|
|
202
|
+
"piv" => 982,
|
|
203
|
+
"plusmn" => 177,
|
|
204
|
+
"pound" => 163,
|
|
205
|
+
"prime" => 8242,
|
|
206
|
+
"prod" => 8719,
|
|
207
|
+
"prop" => 8733,
|
|
208
|
+
"psi" => 968,
|
|
209
|
+
"quot" => 34,
|
|
210
|
+
"rArr" => 8658,
|
|
211
|
+
"radic" => 8730,
|
|
212
|
+
"rang" => 9002,
|
|
213
|
+
"raquo" => 187,
|
|
214
|
+
"rarr" => 8594,
|
|
215
|
+
"rceil" => 8969,
|
|
216
|
+
"rdquo" => 8221,
|
|
217
|
+
"real" => 8476,
|
|
218
|
+
"reg" => 174,
|
|
219
|
+
"rfloor" => 8971,
|
|
220
|
+
"rho" => 961,
|
|
221
|
+
"rlm" => 8207,
|
|
222
|
+
"rsaquo" => 8250,
|
|
223
|
+
"rsquo" => 8217,
|
|
224
|
+
"sbquo" => 8218,
|
|
225
|
+
"scaron" => 353,
|
|
226
|
+
"sdot" => 8901,
|
|
227
|
+
"sect" => 167,
|
|
228
|
+
"shy" => 173,
|
|
229
|
+
"sigma" => 963,
|
|
230
|
+
"sigmaf" => 962,
|
|
231
|
+
"sim" => 8764,
|
|
232
|
+
"spades" => 9824,
|
|
233
|
+
"sub" => 8834,
|
|
234
|
+
"sube" => 8838,
|
|
235
|
+
"sum" => 8721,
|
|
236
|
+
"sup" => 8835,
|
|
237
|
+
"sup1" => 185,
|
|
238
|
+
"sup2" => 178,
|
|
239
|
+
"sup3" => 179,
|
|
240
|
+
"supe" => 8839,
|
|
241
|
+
"szlig" => 223,
|
|
242
|
+
"tau" => 964,
|
|
243
|
+
"there4" => 8756,
|
|
244
|
+
"theta" => 952,
|
|
245
|
+
"thetasym" => 977,
|
|
246
|
+
"thinsp" => 8201,
|
|
247
|
+
"thorn" => 254,
|
|
248
|
+
"tilde" => 732,
|
|
249
|
+
"times" => 215,
|
|
250
|
+
"trade" => 8482,
|
|
251
|
+
"uArr" => 8657,
|
|
252
|
+
"uacute" => 250,
|
|
253
|
+
"uarr" => 8593,
|
|
254
|
+
"ucirc" => 251,
|
|
255
|
+
"ugrave" => 249,
|
|
256
|
+
"uml" => 168,
|
|
257
|
+
"upsih" => 978,
|
|
258
|
+
"upsilon" => 965,
|
|
259
|
+
"uuml" => 252,
|
|
260
|
+
"weierp" => 8472,
|
|
261
|
+
"xi" => 958,
|
|
262
|
+
"yacute" => 253,
|
|
263
|
+
"yen" => 165,
|
|
264
|
+
"yuml" => 255,
|
|
265
|
+
"zeta" => 950,
|
|
266
|
+
"zwj" => 8205,
|
|
267
|
+
"zwnj" => 8204,
|
|
268
|
+
}.freeze
|
|
269
|
+
|
|
270
|
+
NAME_PATTERN = /&(#x?[0-9A-Fa-f]+|[A-Za-z][A-Za-z0-9]*);/
|
|
271
|
+
|
|
272
|
+
module_function
|
|
273
|
+
|
|
274
|
+
def decode(value)
|
|
275
|
+
value.gsub(NAME_PATTERN) do |match|
|
|
276
|
+
body = match[1..-2]
|
|
277
|
+
case body[0]
|
|
278
|
+
when "x", "X"
|
|
279
|
+
body[1..].to_i(16).chr(Encoding::UTF_8)
|
|
280
|
+
when "#"
|
|
281
|
+
body[1..].to_i.chr(Encoding::UTF_8)
|
|
282
|
+
else
|
|
283
|
+
codepoint = NAMED_TO_CODEPOINT[body]
|
|
284
|
+
codepoint ? codepoint.chr(Encoding::UTF_8) : match
|
|
285
|
+
end
|
|
286
|
+
end
|
|
287
|
+
end
|
|
288
|
+
end
|
|
289
|
+
end
|
|
290
|
+
end
|
data/lib/lutaml/xml/mapping.rb
CHANGED
|
@@ -121,9 +121,16 @@ module Lutaml
|
|
|
121
121
|
@cached_attributes.clear
|
|
122
122
|
@cached_mappings.clear
|
|
123
123
|
@cached_attribute_name_counts.clear
|
|
124
|
+
@rule_records_version = (@rule_records_version || 0) + 1
|
|
124
125
|
@finalized = true
|
|
125
126
|
end
|
|
126
127
|
|
|
128
|
+
# Bumped at finalize; ModelTransform's compiled rule records are
|
|
129
|
+
# keyed on it so late mapping changes rebuild instead of going stale.
|
|
130
|
+
def rule_records_version
|
|
131
|
+
@rule_records_version ||= 0
|
|
132
|
+
end
|
|
133
|
+
|
|
127
134
|
def finalized?
|
|
128
135
|
@finalized
|
|
129
136
|
end
|
|
@@ -1334,6 +1341,18 @@ module Lutaml
|
|
|
1334
1341
|
!@namespace_class.nil?
|
|
1335
1342
|
end
|
|
1336
1343
|
|
|
1344
|
+
# lutaml-model#154: opt-in decoding of HTML named/numeric entities
|
|
1345
|
+
# (e.g. ©, —) in mapped text and attribute values. XML
|
|
1346
|
+
# documents are otherwise kept byte-faithful: HTML entities are not
|
|
1347
|
+
# defined in XML without a DTD.
|
|
1348
|
+
def html_entities(enabled: true)
|
|
1349
|
+
@decode_html_entities = enabled
|
|
1350
|
+
end
|
|
1351
|
+
|
|
1352
|
+
def decode_html_entities?
|
|
1353
|
+
!!@decode_html_entities
|
|
1354
|
+
end
|
|
1355
|
+
|
|
1337
1356
|
# Whether namespace was explicitly set via DSL
|
|
1338
1357
|
def namespace_set?
|
|
1339
1358
|
!!@namespace_set
|