stbkit-core 0.1.0a9.dev1__py3-none-any.whl

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.
Files changed (60) hide show
  1. stbkit/core/__init__.py +12 -0
  2. stbkit/core/_internal/constants.py +42 -0
  3. stbkit/core/_internal/extension_utils.py +238 -0
  4. stbkit/core/_internal/io_text.py +48 -0
  5. stbkit/core/_internal/name_converter.py +170 -0
  6. stbkit/core/_internal/optional_dependencies/xmlschema_validator.py +163 -0
  7. stbkit/core/_internal/stb_logger.py +86 -0
  8. stbkit/core/_internal/transform/__init__.py +5 -0
  9. stbkit/core/_internal/transform/guid_tools.py +73 -0
  10. stbkit/core/_internal/transform/select.py +114 -0
  11. stbkit/core/_internal/xml_value_converter.py +16 -0
  12. stbkit/core/data_model/__init__.py +5 -0
  13. stbkit/core/data_model/_internal/filter_option.py +25 -0
  14. stbkit/core/data_model/_internal/stb_types.py +98 -0
  15. stbkit/core/data_model/_internal/type_validation.py +755 -0
  16. stbkit/core/data_model/common.py +967 -0
  17. stbkit/core/data_model/stb_v2_0_0.py +13633 -0
  18. stbkit/core/data_model/stb_v2_0_0.pyi +15327 -0
  19. stbkit/core/data_model/stb_v2_0_1.py +13702 -0
  20. stbkit/core/data_model/stb_v2_0_1.pyi +15450 -0
  21. stbkit/core/data_model/stb_v2_0_2.py +21677 -0
  22. stbkit/core/data_model/stb_v2_0_2.pyi +23319 -0
  23. stbkit/core/data_model/stb_v2_1_0.py +27541 -0
  24. stbkit/core/data_model/stb_v2_1_0.pyi +31553 -0
  25. stbkit/core/data_model/stb_v2_1_1.py +27577 -0
  26. stbkit/core/data_model/stb_v2_1_1.pyi +31590 -0
  27. stbkit/core/py.typed +0 -0
  28. stbkit/core/repository/__init__.py +67 -0
  29. stbkit/core/repository/_internal/ref_def_v2_0_2.py +191 -0
  30. stbkit/core/repository/_internal/ref_def_v2_1_0.py +216 -0
  31. stbkit/core/repository/_internal/ref_def_v2_1_1.py +216 -0
  32. stbkit/core/repository/repo_common.py +363 -0
  33. stbkit/core/repository/repo_v2_0_2.py +48 -0
  34. stbkit/core/repository/repo_v2_0_2.pyi +257 -0
  35. stbkit/core/repository/repo_v2_1_0.py +48 -0
  36. stbkit/core/repository/repo_v2_1_0.pyi +272 -0
  37. stbkit/core/repository/repo_v2_1_1.py +50 -0
  38. stbkit/core/repository/repo_v2_1_1.pyi +272 -0
  39. stbkit/core/serialization/__init__.py +21 -0
  40. stbkit/core/serialization/_dict_converter.py +1448 -0
  41. stbkit/core/serialization/config.py +114 -0
  42. stbkit/core/serialization/profiles.py +57 -0
  43. stbkit/core/stb_exceptions.py +203 -0
  44. stbkit/core/stb_io/__init__.py +17 -0
  45. stbkit/core/stb_io/_internal/__init__.py +5 -0
  46. stbkit/core/stb_io/_internal/loader.py +63 -0
  47. stbkit/core/stb_io/_internal/serializer.py +157 -0
  48. stbkit/core/stb_io/_internal/stream_reader.py +346 -0
  49. stbkit/core/stb_io/_internal/xml_io.py +482 -0
  50. stbkit/core/stb_reporting.py +1061 -0
  51. stbkit/core/stb_typing.py +61 -0
  52. stbkit/core/validation/__init__.py +9 -0
  53. stbkit/core/validation/_internal/common.py +78 -0
  54. stbkit/core/validation/_internal/schema_validator.py +294 -0
  55. stbkit/core/validation/_internal/validator.py +109 -0
  56. stbkit_core-0.1.0a9.dev1.dist-info/METADATA +121 -0
  57. stbkit_core-0.1.0a9.dev1.dist-info/RECORD +60 -0
  58. stbkit_core-0.1.0a9.dev1.dist-info/WHEEL +5 -0
  59. stbkit_core-0.1.0a9.dev1.dist-info/licenses/LICENSE +373 -0
  60. stbkit_core-0.1.0a9.dev1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,755 @@
1
+ # Copyright 2026 TAISEI CORPORATION
2
+ # SPDX-License-Identifier: MPL-2.0
3
+ # This Source Code Form is subject to the terms of the Mozilla Public
4
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
5
+ # file, You can obtain one at https://mozilla.org/MPL/2.0/.
6
+
7
+ from __future__ import annotations
8
+
9
+ from collections.abc import Callable, Sequence
10
+ from enum import Enum
11
+ from typing import TYPE_CHECKING, Any
12
+ from uuid import UUID
13
+
14
+ from ..._internal.name_converter import private_field_name
15
+ from ...stb_exceptions import SchemaError, TypeMismatchError
16
+ from ...stb_typing import (
17
+ Angle,
18
+ Length,
19
+ Monolist,
20
+ MonolistId,
21
+ MonolistLength,
22
+ NonNegativeInteger,
23
+ NonNegativeLength,
24
+ PositiveInteger,
25
+ PositiveIntegerList,
26
+ Ratio,
27
+ )
28
+ from .stb_types import DataType
29
+
30
+ if TYPE_CHECKING:
31
+ from ..common import StBridgeElement, _FieldInfo
32
+
33
+
34
+ def validate_angle(
35
+ value: Any, *, element: StBridgeElement | None = None, attr_name: str | None = None
36
+ ) -> None:
37
+ if not isinstance(value, Angle):
38
+ raise TypeMismatchError(
39
+ expected_type=Angle,
40
+ actual_type=type(value),
41
+ element=element,
42
+ attr_name=attr_name,
43
+ )
44
+ if not (0 <= value < 360):
45
+ raise SchemaError(
46
+ f"angleが0以上360未満でない値です: {value}",
47
+ element=element,
48
+ attr_name=attr_name,
49
+ )
50
+
51
+
52
+ def validate_bool(
53
+ value: Any, *, element: StBridgeElement | None = None, attr_name: str | None = None
54
+ ) -> None:
55
+ if not isinstance(value, bool):
56
+ raise TypeMismatchError(
57
+ expected_type=bool,
58
+ actual_type=type(value),
59
+ element=element,
60
+ attr_name=attr_name,
61
+ )
62
+
63
+
64
+ def validate_enum(value: Any, element: StBridgeElement, attr_name: str) -> None:
65
+ fi = element._field_info(attr_name)
66
+ if not isinstance(fi.py_type, type):
67
+ raise TypeError(f"{element.__class__}.{attr_name}のpy_typeが指定されていません")
68
+ enum_type: type = fi.py_type
69
+ enum_base_type: type
70
+ if issubclass(enum_type, str):
71
+ enum_base_type = str
72
+ elif issubclass(enum_type, int):
73
+ enum_base_type = int
74
+
75
+ if isinstance(value, enum_type):
76
+ return
77
+ if isinstance(value, enum_base_type):
78
+ if not fi.choices:
79
+ raise RuntimeError(
80
+ f"{element.__class__}.{attr_name}のchoicesが指定されていません"
81
+ )
82
+ if str(value) not in fi.choices:
83
+ raise SchemaError(
84
+ f"許容される値ではありません。値:{value} 候補:{fi.choices}",
85
+ element=element,
86
+ attr_name=attr_name,
87
+ )
88
+ else:
89
+ return
90
+ raise TypeMismatchError(
91
+ expected_type=enum_base_type,
92
+ actual_type=type(value),
93
+ element=element,
94
+ attr_name=attr_name,
95
+ )
96
+
97
+
98
+ def validate_float(
99
+ value: Any, *, element: StBridgeElement | None = None, attr_name: str | None = None
100
+ ) -> None:
101
+ if not isinstance(value, float):
102
+ raise TypeMismatchError(
103
+ expected_type=float,
104
+ actual_type=type(value),
105
+ element=element,
106
+ attr_name=attr_name,
107
+ )
108
+
109
+
110
+ def validate_int(
111
+ value: Any, *, element: StBridgeElement | None = None, attr_name: str | None = None
112
+ ) -> None:
113
+ if not isinstance(value, int):
114
+ raise TypeMismatchError(
115
+ expected_type=int,
116
+ actual_type=type(value),
117
+ element=element,
118
+ attr_name=attr_name,
119
+ )
120
+
121
+
122
+ def validate_length(
123
+ value: Any, *, element: StBridgeElement | None = None, attr_name: str | None = None
124
+ ) -> None:
125
+ if not isinstance(value, Length):
126
+ raise TypeMismatchError(
127
+ expected_type=Length,
128
+ actual_type=type(value),
129
+ element=element,
130
+ attr_name=attr_name,
131
+ )
132
+ if value <= 0:
133
+ raise SchemaError(
134
+ f"lengthが0以下です: {value}", element=element, attr_name=attr_name
135
+ )
136
+
137
+
138
+ def validate_monolist(
139
+ value: Any, *, element: StBridgeElement | None = None, attr_name: str | None = None
140
+ ) -> None:
141
+ if not isinstance(value, Sequence) or not all(
142
+ isinstance(item, int) for item in value
143
+ ):
144
+ raise TypeMismatchError(
145
+ expected_type=Monolist,
146
+ actual_type=type(value),
147
+ element=element,
148
+ attr_name=attr_name,
149
+ )
150
+
151
+
152
+ def validate_monolist_id(
153
+ value: Any, *, element: StBridgeElement | None = None, attr_name: str | None = None
154
+ ) -> None:
155
+ if not isinstance(value, Sequence) or not all(
156
+ isinstance(item, int) for item in value
157
+ ):
158
+ raise TypeMismatchError(
159
+ expected_type=MonolistId,
160
+ actual_type=type(value),
161
+ element=element,
162
+ attr_name=attr_name,
163
+ )
164
+ if not all(item > 0 for item in value):
165
+ raise SchemaError(
166
+ f"monolist_idに0以下の値が含まれています: {value}",
167
+ element=element,
168
+ attr_name=attr_name,
169
+ )
170
+
171
+
172
+ def validate_monolist_length(
173
+ value: Any, *, element: StBridgeElement | None = None, attr_name: str | None = None
174
+ ) -> None:
175
+ if not isinstance(value, Sequence) or not all(
176
+ isinstance(item, float) for item in value
177
+ ):
178
+ raise TypeMismatchError(
179
+ expected_type=MonolistLength,
180
+ actual_type=type(value),
181
+ element=element,
182
+ attr_name=attr_name,
183
+ )
184
+
185
+
186
+ def validate_non_negative_integer(
187
+ value: Any, *, element: StBridgeElement | None = None, attr_name: str | None = None
188
+ ) -> None:
189
+ if not isinstance(value, int):
190
+ raise TypeMismatchError(
191
+ expected_type=NonNegativeInteger,
192
+ actual_type=type(value),
193
+ element=element,
194
+ attr_name=attr_name,
195
+ )
196
+ if value < 0:
197
+ raise SchemaError(
198
+ f"non_negative_integerが負の値です: {value}",
199
+ element=element,
200
+ attr_name=attr_name,
201
+ )
202
+
203
+
204
+ def validate_non_negative_length(
205
+ value: Any, *, element: StBridgeElement | None = None, attr_name: str | None = None
206
+ ) -> None:
207
+ if not isinstance(value, float):
208
+ raise TypeMismatchError(
209
+ expected_type=NonNegativeLength,
210
+ actual_type=type(value),
211
+ element=element,
212
+ attr_name=attr_name,
213
+ )
214
+ if value < 0:
215
+ raise SchemaError(
216
+ f"non_negative_lengthが負の値です: {value}",
217
+ element=element,
218
+ attr_name=attr_name,
219
+ )
220
+
221
+
222
+ def validate_positive_integer(
223
+ value: Any, *, element: StBridgeElement | None = None, attr_name: str | None = None
224
+ ) -> None:
225
+ if not isinstance(value, int):
226
+ raise TypeMismatchError(
227
+ expected_type=PositiveInteger,
228
+ actual_type=type(value),
229
+ element=element,
230
+ attr_name=attr_name,
231
+ )
232
+ if value <= 0:
233
+ raise SchemaError(
234
+ f"positive_integerが0以下の値です: {value}",
235
+ element=element,
236
+ attr_name=attr_name,
237
+ )
238
+
239
+
240
+ def validate_positive_integer_list(
241
+ value: Any, *, element: StBridgeElement | None = None, attr_name: str | None = None
242
+ ) -> None:
243
+ if not isinstance(value, Sequence) or not all(
244
+ isinstance(item, int) for item in value
245
+ ):
246
+ raise TypeMismatchError(
247
+ expected_type=PositiveIntegerList,
248
+ actual_type=type(value),
249
+ element=element,
250
+ attr_name=attr_name,
251
+ )
252
+ if not all(item > 0 for item in value):
253
+ raise SchemaError(
254
+ f"positive_integer_listに0以下の値が含まれています: {value}",
255
+ element=element,
256
+ attr_name=attr_name,
257
+ )
258
+
259
+
260
+ def validate_ratio(
261
+ value: Any, *, element: StBridgeElement | None = None, attr_name: str | None = None
262
+ ) -> None:
263
+ if not isinstance(value, float):
264
+ raise TypeMismatchError(
265
+ expected_type=Ratio,
266
+ actual_type=type(value),
267
+ element=element,
268
+ attr_name=attr_name,
269
+ )
270
+ if not (0 < value < 1):
271
+ raise SchemaError(
272
+ f"ratioが0以上1以下でない値です: {value}",
273
+ element=element,
274
+ attr_name=attr_name,
275
+ )
276
+
277
+
278
+ def validate_str(
279
+ value: Any, *, element: StBridgeElement | None = None, attr_name: str | None = None
280
+ ) -> None:
281
+ if not isinstance(value, str):
282
+ raise TypeMismatchError(
283
+ expected_type=str,
284
+ actual_type=type(value),
285
+ element=element,
286
+ attr_name=attr_name,
287
+ )
288
+
289
+
290
+ def validate_uuid(
291
+ value: Any, *, element: StBridgeElement | None = None, attr_name: str | None = None
292
+ ) -> None:
293
+ if not isinstance(value, UUID):
294
+ raise TypeMismatchError(
295
+ expected_type=UUID,
296
+ actual_type=type(value),
297
+ element=element,
298
+ attr_name=attr_name,
299
+ )
300
+
301
+
302
+ def str_to_angle(
303
+ value: str, *, element: StBridgeElement | None = None, attr_name: str | None = None
304
+ ) -> Angle:
305
+ try:
306
+ result: Angle = float(value)
307
+ validate_angle(result, element=element, attr_name=attr_name)
308
+ return result
309
+ except (TypeError, ValueError):
310
+ raise SchemaError(
311
+ f"angleに変換できない値です: {value}", element=element, attr_name=attr_name
312
+ )
313
+
314
+
315
+ def str_to_bool(
316
+ value: str, *, element: StBridgeElement | None = None, attr_name: str | None = None
317
+ ) -> bool:
318
+ match value.lower():
319
+ case "true":
320
+ return True
321
+ case "false":
322
+ return False
323
+ case _:
324
+ raise SchemaError(
325
+ f"boolに変換できない値です: {value}",
326
+ element=element,
327
+ attr_name=attr_name,
328
+ )
329
+
330
+
331
+ def str_to_enum(
332
+ value: str, *, element: StBridgeElement | None, attr_name: str | None
333
+ ) -> Enum:
334
+ if element is None or attr_name is None:
335
+ raise RuntimeError()
336
+ fi = element._field_info(attr_name)
337
+ enum_type = fi.py_type
338
+ if isinstance(enum_type, str):
339
+ raise TypeError()
340
+ if not issubclass(enum_type, Enum):
341
+ raise TypeError()
342
+ try:
343
+ return enum_type(value)
344
+ except (TypeError, ValueError):
345
+ raise SchemaError(
346
+ f"{enum_type}に変換できない値です: {value}",
347
+ element=element,
348
+ attr_name=attr_name,
349
+ )
350
+
351
+
352
+ def str_to_float(
353
+ value: str, *, element: StBridgeElement | None = None, attr_name: str | None = None
354
+ ) -> float:
355
+ try:
356
+ return float(value)
357
+ except (TypeError, ValueError):
358
+ raise SchemaError(
359
+ f"floatに変換できない値です: {value}", element=element, attr_name=attr_name
360
+ )
361
+
362
+
363
+ def str_to_int(
364
+ value: str, *, element: StBridgeElement | None = None, attr_name: str | None = None
365
+ ) -> int:
366
+ try:
367
+ return int(value)
368
+ except (TypeError, ValueError):
369
+ raise SchemaError(
370
+ f"intに変換できない値です: {value}", element=element, attr_name=attr_name
371
+ )
372
+
373
+
374
+ def str_to_length(
375
+ value: str, *, element: StBridgeElement | None = None, attr_name: str | None = None
376
+ ) -> Length:
377
+ try:
378
+ result: Length = float(value)
379
+ validate_length(result, element=element, attr_name=attr_name)
380
+ return result
381
+ except (TypeError, ValueError):
382
+ raise SchemaError(
383
+ f"lengthに変換できない値です: {value}", element=element, attr_name=attr_name
384
+ )
385
+
386
+
387
+ def str_to_monolist(
388
+ value: str, *, element: StBridgeElement | None = None, attr_name: str | None = None
389
+ ) -> Monolist:
390
+ try:
391
+ items = value.split(" ")
392
+ result: Monolist = [int(item.strip()) for item in items]
393
+ validate_monolist(result, element=element, attr_name=attr_name)
394
+ return result
395
+ except (TypeError, ValueError):
396
+ raise SchemaError(
397
+ f"monolistに変換できない値です: {value}",
398
+ element=element,
399
+ attr_name=attr_name,
400
+ )
401
+
402
+
403
+ def str_to_monolist_id(
404
+ value: str, *, element: StBridgeElement | None = None, attr_name: str | None = None
405
+ ) -> MonolistId:
406
+ try:
407
+ items = value.split(" ")
408
+ result: MonolistId = [int(item.strip()) for item in items]
409
+ validate_monolist_id(result, element=element, attr_name=attr_name)
410
+ return result
411
+ except (TypeError, ValueError):
412
+ raise SchemaError(
413
+ f"monolist_idに変換できない値です: {value}",
414
+ element=element,
415
+ attr_name=attr_name,
416
+ )
417
+
418
+
419
+ def str_to_monolist_length(
420
+ value: str, *, element: StBridgeElement | None = None, attr_name: str | None = None
421
+ ) -> MonolistLength:
422
+ try:
423
+ items = value.split(" ")
424
+ result: MonolistLength = [float(item.strip()) for item in items]
425
+ validate_monolist_length(result, element=element, attr_name=attr_name)
426
+ return result
427
+ except (TypeError, ValueError):
428
+ raise SchemaError(
429
+ f"monolist_lengthに変換できない値です: {value}",
430
+ element=element,
431
+ attr_name=attr_name,
432
+ )
433
+
434
+
435
+ def str_to_non_negative_integer(
436
+ value: str, *, element: StBridgeElement | None = None, attr_name: str | None = None
437
+ ) -> NonNegativeInteger:
438
+ try:
439
+ result: NonNegativeInteger = int(value)
440
+ validate_non_negative_integer(result, element=element, attr_name=attr_name)
441
+ return result
442
+ except (TypeError, ValueError):
443
+ raise SchemaError(
444
+ f"non_negative_integerに変換できない値です: {value}",
445
+ element=element,
446
+ attr_name=attr_name,
447
+ )
448
+
449
+
450
+ def str_to_non_negative_length(
451
+ value: str, *, element: StBridgeElement | None = None, attr_name: str | None = None
452
+ ) -> NonNegativeLength:
453
+ try:
454
+ result: NonNegativeLength = float(value)
455
+ validate_non_negative_length(result, element=element, attr_name=attr_name)
456
+ return result
457
+ except (TypeError, ValueError):
458
+ raise SchemaError(
459
+ f"non_negative_lengthに変換できない値です: {value}",
460
+ element=element,
461
+ attr_name=attr_name,
462
+ )
463
+
464
+
465
+ def str_to_positive_integer(
466
+ value: str, *, element: StBridgeElement | None = None, attr_name: str | None = None
467
+ ) -> PositiveInteger:
468
+ try:
469
+ result: PositiveInteger = int(value)
470
+ validate_positive_integer(result, element=element, attr_name=attr_name)
471
+ return result
472
+ except (TypeError, ValueError):
473
+ raise SchemaError(
474
+ f"positive_integerに変換できない値です: {value}",
475
+ element=element,
476
+ attr_name=attr_name,
477
+ )
478
+
479
+
480
+ def str_to_positive_integer_list(
481
+ value: str, *, element: StBridgeElement | None = None, attr_name: str | None = None
482
+ ) -> PositiveIntegerList:
483
+ try:
484
+ items = value.split(" ")
485
+ result: PositiveIntegerList = [int(item.strip()) for item in items]
486
+ validate_positive_integer_list(result, element=element, attr_name=attr_name)
487
+ return result
488
+ except (TypeError, ValueError):
489
+ raise SchemaError(
490
+ f"positive_integer_listに変換できない値です: {value}",
491
+ element=element,
492
+ attr_name=attr_name,
493
+ )
494
+
495
+
496
+ def str_to_ratio(
497
+ value: str, *, element: StBridgeElement | None = None, attr_name: str | None = None
498
+ ) -> Ratio:
499
+ try:
500
+ result: Ratio = float(value)
501
+ validate_ratio(result, element=element, attr_name=attr_name)
502
+ return result
503
+ except (TypeError, ValueError):
504
+ raise SchemaError(
505
+ f"ratioに変換できない値です: {value}", element=element, attr_name=attr_name
506
+ )
507
+
508
+
509
+ def str_to_str(
510
+ value: str, *, element: StBridgeElement | None = None, attr_name: str | None = None
511
+ ) -> str:
512
+ if not isinstance(value, str):
513
+ raise SchemaError(
514
+ f"strに変換できない値です: {value}", element=element, attr_name=attr_name
515
+ )
516
+ return value
517
+
518
+
519
+ def str_to_uuid(
520
+ value: str, *, element: StBridgeElement | None = None, attr_name: str | None = None
521
+ ) -> UUID:
522
+ try:
523
+ result: UUID = UUID(value)
524
+ validate_uuid(result, element=element, attr_name=attr_name)
525
+ return result
526
+ except (ValueError, AttributeError):
527
+ raise SchemaError(
528
+ f"UUIDに変換できない値です: {value}", element=element, attr_name=attr_name
529
+ )
530
+
531
+
532
+ def str_to_typed_value(
533
+ value: str,
534
+ data_type: DataType,
535
+ *,
536
+ element: StBridgeElement | None = None,
537
+ attr_name: str | None = None,
538
+ ) -> Any:
539
+ match data_type:
540
+ case DataType.ANGLE:
541
+ return str_to_angle(value, element=element, attr_name=attr_name)
542
+ case DataType.BOOL:
543
+ return str_to_bool(value, element=element, attr_name=attr_name)
544
+ case DataType.FLOAT:
545
+ return str_to_float(value, element=element, attr_name=attr_name)
546
+ case DataType.INT:
547
+ return str_to_int(value, element=element, attr_name=attr_name)
548
+ case DataType.LENGTH:
549
+ return str_to_length(value, element=element, attr_name=attr_name)
550
+ case DataType.MONOLIST:
551
+ return str_to_monolist(value, element=element, attr_name=attr_name)
552
+ case DataType.MONOLIST_LENGTH:
553
+ return str_to_monolist_length(value, element=element, attr_name=attr_name)
554
+ case DataType.MONOLIST_ID:
555
+ return str_to_monolist_id(value, element=element, attr_name=attr_name)
556
+ case DataType.NON_NEGATIVE_INTEGER:
557
+ return str_to_non_negative_integer(
558
+ value, element=element, attr_name=attr_name
559
+ )
560
+ case DataType.NON_NEGATIVE_LENGTH:
561
+ return str_to_non_negative_length(
562
+ value, element=element, attr_name=attr_name
563
+ )
564
+ case DataType.POSITIVE_INTEGER:
565
+ return str_to_positive_integer(value, element=element, attr_name=attr_name)
566
+ case DataType.POSITIVE_INTEGER_LIST:
567
+ return str_to_positive_integer_list(
568
+ value, element=element, attr_name=attr_name
569
+ )
570
+ case DataType.RATIO:
571
+ return str_to_ratio(value, element=element, attr_name=attr_name)
572
+ case DataType.STR:
573
+ return str_to_str(value, element=element, attr_name=attr_name)
574
+ case DataType.UUID:
575
+ return str_to_uuid(value, element=element, attr_name=attr_name)
576
+ case DataType.INT_ENUM | DataType.STR_ENUM:
577
+ return str_to_enum(value, element=element, attr_name=attr_name)
578
+ case _:
579
+ raise NotImplementedError(f"未対応のDataTypeです: {data_type}")
580
+
581
+
582
+ def any_to_typed_value(
583
+ value: Any,
584
+ data_type: DataType,
585
+ *,
586
+ element: StBridgeElement | None = None,
587
+ attr_name: str | None = None,
588
+ ) -> Any:
589
+ if data_type == DataType.MONOLIST:
590
+ validate_monolist(value, element=element, attr_name=attr_name)
591
+ return value
592
+ elif data_type == DataType.MONOLIST_LENGTH:
593
+ validate_monolist_length(value, element=element, attr_name=attr_name)
594
+ return value
595
+ elif data_type == DataType.MONOLIST_ID:
596
+ validate_monolist_id(value, element=element, attr_name=attr_name)
597
+ return value
598
+ elif data_type == DataType.POSITIVE_INTEGER_LIST:
599
+ validate_positive_integer_list(value, element=element, attr_name=attr_name)
600
+ return value
601
+ elif data_type in (DataType.INT_ENUM, DataType.STR_ENUM):
602
+ if element is None or attr_name is None:
603
+ raise RuntimeError("enum変換にはelementとattr_nameが必要です")
604
+ fi: _FieldInfo = element._field_info(attr_name)
605
+ enum_type = fi.py_type
606
+ if not isinstance(enum_type, type) or not issubclass(enum_type, Enum):
607
+ raise TypeError(
608
+ f"{element.__class__.__name__}.{attr_name}のenum型情報が不正です"
609
+ )
610
+ validate_enum(value, element=element, attr_name=attr_name)
611
+ if isinstance(value, enum_type):
612
+ return value
613
+ return enum_type(value)
614
+ elif isinstance(value, data_type.to_type()):
615
+ return value
616
+ elif isinstance(value, str):
617
+ return str_to_typed_value(
618
+ value, data_type, element=element, attr_name=attr_name
619
+ )
620
+ else:
621
+ raise TypeMismatchError(
622
+ expected_type=data_type.to_type(),
623
+ actual_type=type(value),
624
+ element=element,
625
+ attr_name=attr_name,
626
+ )
627
+
628
+
629
+ def make_attribute_setter(
630
+ key: str, data_type: DataType, has_choice: bool
631
+ ) -> Callable[[StBridgeElement, Any], None]:
632
+ p_name: str = private_field_name(key)
633
+
634
+ def setter_angle(self: StBridgeElement, value: Any) -> None:
635
+ if value is not None:
636
+ validate_angle(value, element=self, attr_name=key)
637
+ setattr(self, p_name, value)
638
+
639
+ def setter_bool(self: StBridgeElement, value: Any) -> None:
640
+ if value is not None:
641
+ validate_bool(value, element=self, attr_name=key)
642
+ setattr(self, p_name, value)
643
+
644
+ def setter_enum(self: StBridgeElement, value: Any) -> None:
645
+ if value is not None:
646
+ validate_enum(value, element=self, attr_name=key)
647
+ if isinstance(value, Enum):
648
+ setattr(self, p_name, value)
649
+ fi = self._field_info(key)
650
+ if not isinstance(fi.py_type, type):
651
+ raise RuntimeError()
652
+ enum_type: type = fi.py_type
653
+ value = enum_type(value)
654
+ setattr(self, p_name, value)
655
+
656
+ def setter_float(self: StBridgeElement, value: Any) -> None:
657
+ if value is not None:
658
+ validate_float(value, element=self, attr_name=key)
659
+ setattr(self, p_name, value)
660
+
661
+ def setter_int(self: StBridgeElement, value: Any) -> None:
662
+ if value is not None:
663
+ validate_int(value, element=self, attr_name=key)
664
+ setattr(self, p_name, value)
665
+
666
+ def setter_length(self: StBridgeElement, value: Any) -> None:
667
+ if value is not None:
668
+ validate_length(value, element=self, attr_name=key)
669
+ setattr(self, p_name, value)
670
+
671
+ def setter_monolist(self: StBridgeElement, value: Any) -> None:
672
+ if value is not None:
673
+ validate_monolist(value, element=self, attr_name=key)
674
+ setattr(self, p_name, value)
675
+
676
+ def setter_monolist_id(self: StBridgeElement, value: Any) -> None:
677
+ if value is not None:
678
+ validate_monolist_id(value, element=self, attr_name=key)
679
+ setattr(self, p_name, value)
680
+
681
+ def setter_monolist_length(self: StBridgeElement, value: Any) -> None:
682
+ if value is not None:
683
+ validate_monolist_length(value, element=self, attr_name=key)
684
+ setattr(self, p_name, value)
685
+
686
+ def setter_non_negative_integer(self: StBridgeElement, value: Any) -> None:
687
+ if value is not None:
688
+ validate_non_negative_integer(value, element=self, attr_name=key)
689
+ setattr(self, p_name, value)
690
+
691
+ def setter_non_negative_length(self: StBridgeElement, value: Any) -> None:
692
+ if value is not None:
693
+ validate_non_negative_length(value, element=self, attr_name=key)
694
+ setattr(self, p_name, value)
695
+
696
+ def setter_positive_integer(self: StBridgeElement, value: Any) -> None:
697
+ if value is not None:
698
+ validate_positive_integer(value, element=self, attr_name=key)
699
+ setattr(self, p_name, value)
700
+
701
+ def setter_positive_integer_list(self: StBridgeElement, value: Any) -> None:
702
+ if value is not None:
703
+ validate_positive_integer_list(value, element=self, attr_name=key)
704
+ setattr(self, p_name, value)
705
+
706
+ def setter_ratio(self: StBridgeElement, value: Any) -> None:
707
+ if value is not None:
708
+ validate_ratio(value, element=self, attr_name=key)
709
+ setattr(self, p_name, value)
710
+
711
+ def setter_str(self: StBridgeElement, value: Any) -> None:
712
+ if value is not None:
713
+ validate_str(value, element=self, attr_name=key)
714
+ setattr(self, p_name, value)
715
+
716
+ def setter_uuid(self: StBridgeElement, value: Any) -> None:
717
+ if value is not None:
718
+ validate_uuid(value, element=self, attr_name=key)
719
+ setattr(self, p_name, value)
720
+
721
+ if has_choice:
722
+ return setter_enum
723
+ match data_type:
724
+ case DataType.ANGLE:
725
+ return setter_angle
726
+ case DataType.BOOL:
727
+ return setter_bool
728
+ case DataType.FLOAT:
729
+ return setter_float
730
+ case DataType.INT:
731
+ return setter_int
732
+ case DataType.LENGTH:
733
+ return setter_length
734
+ case DataType.MONOLIST:
735
+ return setter_monolist
736
+ case DataType.MONOLIST_LENGTH:
737
+ return setter_monolist_length
738
+ case DataType.MONOLIST_ID:
739
+ return setter_monolist_id
740
+ case DataType.NON_NEGATIVE_INTEGER:
741
+ return setter_non_negative_integer
742
+ case DataType.NON_NEGATIVE_LENGTH:
743
+ return setter_non_negative_length
744
+ case DataType.POSITIVE_INTEGER:
745
+ return setter_positive_integer
746
+ case DataType.POSITIVE_INTEGER_LIST:
747
+ return setter_positive_integer_list
748
+ case DataType.RATIO:
749
+ return setter_ratio
750
+ case DataType.STR:
751
+ return setter_str
752
+ case DataType.UUID:
753
+ return setter_uuid
754
+ case _:
755
+ raise NotImplementedError(f"未対応のDataTypeです: {data_type}")