Coverage for sbe2/schema/type.py: 96%
45 statements
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-21 19:48 +0200
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-21 19:48 +0200
1from .common import FixedLengthElement, Presence
2from .primitive_type import PrimitiveType
3from dataclasses import dataclass
4from functools import cached_property
5from typing import Any, override
9# TODO: move
11def value_ref_to_valid_value(value_ref:str, types):
12 from .enum import Enum
13 enum_name, valid_value = value_ref.split('.')
14 enum = types[enum_name]
15 if not isinstance(enum, Enum):
16 raise ValueError(f"'{enum_name}' type is not enum")
17 for vv in enum.valid_values:
18 if vv.name == valid_value:
19 return vv
20 raise ValueError(f"Enum '{enum_name}' does not contain value '{valid_value}'")
22@dataclass
23class Type(FixedLengthElement):
24 """
25 Represents a type element in the schema.
26 This is used to define a specific type of data.
27 """
29 presence: Presence
30 primitive_type: PrimitiveType
31 length: int = 1 # Length of an array, by default just one element
32 offset: int | None = None # Offset in bytes, if applicable
33 since_version: int = 0 # Version since this type is present
34 deprecated: int | None = None # Version this type was deprecated, if applicable
35 value_ref: str | None = None # constant value reference
36 value: str | None = None # constant value of the given field
37 const_val: Any = None # constant value translated into Python type
39 def lazy_bind(self, types):
40 if self.presence is Presence.CONSTANT and self.const_val is None:
41 if self.value_ref:
42 vv = value_ref_to_valid_value(self.value_ref, types)
43 self.const_val = vv.value
44 elif self.value:
45 self.const_val = self.parse(self.value)
46 else:
47 raise ValueError(f"Type '{self.name}' is constant but does not have any constant value assigned")
49 @cached_property
50 @override
51 def total_length(self):
52 if self.presence is Presence.CONSTANT:
53 return 0
54 return self.primitive_type.length
57 @override
58 def parse(self, val: str):
59 if self.length == 1:
60 return self.primitive_type.base_type(val)
61 raise NotImplementedError