labfreed 0.2.8__py3-none-any.whl → 0.2.9__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.

Potentially problematic release.


This version of labfreed might be problematic. Click here for more details.

Files changed (44) hide show
  1. labfreed/__init__.py +11 -11
  2. labfreed/labfreed_infrastructure.py +258 -258
  3. labfreed/pac_cat/__init__.py +19 -19
  4. labfreed/pac_cat/category_base.py +51 -51
  5. labfreed/pac_cat/pac_cat.py +150 -150
  6. labfreed/pac_cat/predefined_categories.py +200 -200
  7. labfreed/pac_id/__init__.py +19 -19
  8. labfreed/pac_id/extension.py +48 -48
  9. labfreed/pac_id/id_segment.py +89 -89
  10. labfreed/pac_id/pac_id.py +140 -140
  11. labfreed/pac_id/url_parser.py +155 -155
  12. labfreed/pac_id/url_serializer.py +85 -84
  13. labfreed/pac_id_resolver/__init__.py +2 -2
  14. labfreed/pac_id_resolver/cit_common.py +81 -81
  15. labfreed/pac_id_resolver/cit_v1.py +244 -244
  16. labfreed/pac_id_resolver/cit_v2.py +313 -313
  17. labfreed/pac_id_resolver/resolver.py +97 -97
  18. labfreed/pac_id_resolver/services.py +82 -82
  19. labfreed/qr/__init__.py +1 -1
  20. labfreed/qr/generate_qr.py +422 -422
  21. labfreed/trex/__init__.py +16 -16
  22. labfreed/trex/python_convenience/__init__.py +3 -3
  23. labfreed/trex/python_convenience/data_table.py +87 -87
  24. labfreed/trex/python_convenience/pyTREX.py +248 -248
  25. labfreed/trex/python_convenience/quantity.py +66 -66
  26. labfreed/trex/table_segment.py +245 -245
  27. labfreed/trex/trex.py +69 -69
  28. labfreed/trex/trex_base_models.py +209 -209
  29. labfreed/trex/value_segments.py +99 -99
  30. labfreed/utilities/base36.py +82 -82
  31. labfreed/well_known_extensions/__init__.py +4 -4
  32. labfreed/well_known_extensions/default_extension_interpreters.py +6 -6
  33. labfreed/well_known_extensions/display_name_extension.py +40 -40
  34. labfreed/well_known_extensions/trex_extension.py +30 -30
  35. labfreed/well_known_keys/gs1/__init__.py +5 -5
  36. labfreed/well_known_keys/gs1/gs1.py +3 -3
  37. labfreed/well_known_keys/labfreed/well_known_keys.py +15 -15
  38. labfreed/well_known_keys/unece/__init__.py +3 -3
  39. labfreed/well_known_keys/unece/unece_units.py +67 -67
  40. {labfreed-0.2.8.dist-info → labfreed-0.2.9.dist-info}/METADATA +11 -8
  41. labfreed-0.2.9.dist-info/RECORD +45 -0
  42. {labfreed-0.2.8.dist-info → labfreed-0.2.9.dist-info}/licenses/LICENSE +21 -21
  43. labfreed-0.2.8.dist-info/RECORD +0 -45
  44. {labfreed-0.2.8.dist-info → labfreed-0.2.9.dist-info}/WHEEL +0 -0
@@ -1,209 +1,209 @@
1
- from datetime import datetime, time
2
- import re
3
-
4
-
5
-
6
- from pydantic import PrivateAttr, model_validator
7
- from labfreed.labfreed_infrastructure import LabFREED_BaseModel, ValidationMsgLevel, _quote_texts
8
- from abc import ABC, abstractmethod
9
-
10
-
11
-
12
- ''' Configure pdoc'''
13
- v_segs = ["NumericSegment",
14
- "DateSegment",
15
- "BoolSegment",
16
- "AlphanumericSegment",
17
- "TextSegment",
18
- "BinarySegment"]
19
- __all__ = ["TREX"] + v_segs + ["TableSegment"] # noqa: F822
20
-
21
-
22
-
23
-
24
- class Value(LabFREED_BaseModel, ABC):
25
- '''@private
26
- Helper to add validation for various types to ValueSegments and Tables
27
- '''
28
- value:str
29
-
30
- def serialize(self):
31
- return self.value
32
-
33
-
34
-
35
- class NumericValue(Value):
36
-
37
- @model_validator(mode='after')
38
- def _validate(self):
39
- value = self.value
40
- if not_allowed_chars := set(re.sub(r'[0-9\.\-E]', '', value)):
41
- self._add_validation_message(
42
- source=f"TREX numeric value {value}",
43
- level=ValidationMsgLevel.ERROR,
44
- msg=f"Characters {_quote_texts(not_allowed_chars)} are not allowed in quantity segment. Must be a number.",
45
- highlight_pattern = f'{value}',
46
- highlight_sub=not_allowed_chars
47
- )
48
- if not re.fullmatch(r'-?\d+(\.\d+)?(E-?\d+)?', value):
49
- self._add_validation_message(
50
- source=f"TREX numeric value {value}",
51
- level=ValidationMsgLevel.ERROR,
52
- msg=f"{value} cannot be converted to number",
53
- highlight_pattern = f'{value}'
54
- )
55
- return self
56
-
57
- class DateValue(Value):
58
- _date_time_dict:dict|None = PrivateAttr(default=None)
59
-
60
- @model_validator(mode='after')
61
- def _validate(self):
62
- pattern:str = r'((?P<year>\d{4})(?P<month>\d{2})(?P<day>\d{2}))?(T(?P<hour>\d{2})(?P<minute>\d{2})(?P<second>\d{2})?(\.(?P<millisecond>\d{3}))?)?'
63
- value=self.value
64
- if not re.fullmatch(pattern, value):
65
- self._add_validation_message(
66
- source=f"TREX date value {value}",
67
- level=ValidationMsgLevel.ERROR,
68
- msg=f'{value} is not in a valid format. Valid format for date: YYYYMMDD; Valid for time: THHMM, THHMMSS, THHMMSS.SSS; Datetime any combination of valid date and time',
69
- highlight_pattern = f'{value}'
70
- )
71
- return self
72
-
73
- matches = re.match(pattern, value)
74
- d = matches.groupdict()
75
- d = {k: int(v) for k,v in d.items() if v }
76
- if 'millisecond' in d.keys():
77
- ms = d.pop('millisecond')
78
- d.update({'microsecond': ms * 1000})
79
- try:
80
- if d.get('year'): # input is only a time
81
- datetime(**d)
82
- else:
83
- time(**d)
84
- except ValueError:
85
- self._add_validation_message(
86
- source=f"TREX date value {value}",
87
- level=ValidationMsgLevel.ERROR,
88
- msg=f'{value} is no valid date or time.',
89
- highlight_pattern = f'{value}'
90
- )
91
-
92
- self._date_time_dict = d
93
- return self
94
-
95
-
96
- class BoolValue(Value):
97
-
98
- @model_validator(mode='after')
99
- def _validate(self):
100
- if self.value not in ['T', 'F']:
101
- self._add_validation_message(
102
- source=f"TREX boolean value {self.value}",
103
- level= ValidationMsgLevel.ERROR,
104
- msg=f'{self.value} is no valid boolean. Must be T or F',
105
- highlight_pattern = f'{self.value}',
106
- highlight_sub=[c for c in self.value]
107
- )
108
- return self
109
-
110
-
111
- class AlphanumericValue(Value):
112
-
113
- @model_validator(mode='after')
114
- def _validate(self):
115
- if re.match(r'[a-z]', self.value):
116
- self._add_validation_message(
117
- source=f"TREX value {self.value}",
118
- level= ValidationMsgLevel.ERROR,
119
- msg="Lower case characters are not allowed.",
120
- highlight_pattern = self.value
121
- )
122
-
123
- if not_allowed_chars := set(re.sub(r'[A-Z0-9\.-]', '', self.value)):
124
- self._add_validation_message(
125
- source=f"TREX value {self.value}",
126
- level= ValidationMsgLevel.ERROR,
127
- msg=f"Characters {_quote_texts(not_allowed_chars)} are not allowed in alphanumeric segment",
128
- highlight_pattern = self.value,
129
- highlight_sub=not_allowed_chars
130
- )
131
- return self
132
-
133
-
134
- class TextValue(Value):
135
-
136
- @model_validator(mode='after')
137
- def _validate(self):
138
- if not_allowed_chars := set(re.sub(r'[A-Z0-9]', '', self.value)):
139
- self._add_validation_message(
140
- source=f"TREX value {self.value}",
141
- level= ValidationMsgLevel.ERROR,
142
- msg=f"Characters {_quote_texts(not_allowed_chars)} are not allowed in text segment. Base36 encoding only allows A-Z0-9",
143
- highlight_pattern = self.value,
144
- highlight_sub=not_allowed_chars
145
- )
146
- return self
147
-
148
-
149
- class BinaryValue(Value):
150
-
151
- @model_validator(mode='after')
152
- def _validate(self):
153
- if not_allowed_chars := set(re.sub(r'[A-Z0-9]', '', self.value)):
154
- self._add_validation_message(
155
- source=f"TREX value {self.value}",
156
- level= ValidationMsgLevel.ERROR,
157
- msg=f"Characters {_quote_texts(not_allowed_chars)} are not allowed in text segment. Base36 encoding only allows A-Z0-9",
158
- highlight_pattern = self.value,
159
- highlight_sub=not_allowed_chars
160
- )
161
- return self
162
-
163
-
164
- class ErrorValue(Value):
165
-
166
- @model_validator(mode='after')
167
- def _validate(self):
168
- if not_allowed_chars := set(re.sub(r'[A-Z0-9\.-]', '', self.value)):
169
- self._add_validation_message(
170
- source=f"TREX value {self.value}",
171
- level= ValidationMsgLevel.ERROR,
172
- msg=f"Characters {_quote_texts(not_allowed_chars)} are not allowed in error segment",
173
- highlight_pattern = self.value,
174
- highlight_sub=not_allowed_chars
175
- )
176
- return self
177
-
178
-
179
- class TREX_Segment(LabFREED_BaseModel, ABC):
180
- '''@private
181
- Abstract class representing a TREX_Segment
182
- '''
183
- key: str
184
-
185
- @abstractmethod
186
- def serialize(self):
187
- raise NotImplementedError("Subclasses must implement 'serialize_as_trex()' method")
188
-
189
-
190
- @model_validator(mode='after')
191
- def _validate_key(self):
192
- if not_allowed_chars := set(re.sub(r'[A-Z0-9\.-]', '', self.key)):
193
- self._add_validation_message(
194
- source=f"TREX segment key {self.key}",
195
- level=ValidationMsgLevel.ERROR,
196
- msg=f"Segment key contains invalid characters: {_quote_texts(not_allowed_chars)}",
197
- highlight_pattern = f'{self.key}$',
198
- highlight_sub=not_allowed_chars
199
- )
200
- return self
201
-
202
-
203
-
204
-
205
-
206
-
207
-
208
-
209
-
1
+ from datetime import datetime, time
2
+ import re
3
+
4
+
5
+
6
+ from pydantic import PrivateAttr, model_validator
7
+ from labfreed.labfreed_infrastructure import LabFREED_BaseModel, ValidationMsgLevel, _quote_texts
8
+ from abc import ABC, abstractmethod
9
+
10
+
11
+
12
+ ''' Configure pdoc'''
13
+ v_segs = ["NumericSegment",
14
+ "DateSegment",
15
+ "BoolSegment",
16
+ "AlphanumericSegment",
17
+ "TextSegment",
18
+ "BinarySegment"]
19
+ __all__ = ["TREX"] + v_segs + ["TableSegment"] # noqa: F822
20
+
21
+
22
+
23
+
24
+ class Value(LabFREED_BaseModel, ABC):
25
+ '''@private
26
+ Helper to add validation for various types to ValueSegments and Tables
27
+ '''
28
+ value:str
29
+
30
+ def serialize(self):
31
+ return self.value
32
+
33
+
34
+
35
+ class NumericValue(Value):
36
+
37
+ @model_validator(mode='after')
38
+ def _validate(self):
39
+ value = self.value
40
+ if not_allowed_chars := set(re.sub(r'[0-9\.\-E]', '', value)):
41
+ self._add_validation_message(
42
+ source=f"TREX numeric value {value}",
43
+ level=ValidationMsgLevel.ERROR,
44
+ msg=f"Characters {_quote_texts(not_allowed_chars)} are not allowed in quantity segment. Must be a number.",
45
+ highlight_pattern = f'{value}',
46
+ highlight_sub=not_allowed_chars
47
+ )
48
+ if not re.fullmatch(r'-?\d+(\.\d+)?(E-?\d+)?', value):
49
+ self._add_validation_message(
50
+ source=f"TREX numeric value {value}",
51
+ level=ValidationMsgLevel.ERROR,
52
+ msg=f"{value} cannot be converted to number",
53
+ highlight_pattern = f'{value}'
54
+ )
55
+ return self
56
+
57
+ class DateValue(Value):
58
+ _date_time_dict:dict|None = PrivateAttr(default=None)
59
+
60
+ @model_validator(mode='after')
61
+ def _validate(self):
62
+ pattern:str = r'((?P<year>\d{4})(?P<month>\d{2})(?P<day>\d{2}))?(T(?P<hour>\d{2})(?P<minute>\d{2})(?P<second>\d{2})?(\.(?P<millisecond>\d{3}))?)?'
63
+ value=self.value
64
+ if not re.fullmatch(pattern, value):
65
+ self._add_validation_message(
66
+ source=f"TREX date value {value}",
67
+ level=ValidationMsgLevel.ERROR,
68
+ msg=f'{value} is not in a valid format. Valid format for date: YYYYMMDD; Valid for time: THHMM, THHMMSS, THHMMSS.SSS; Datetime any combination of valid date and time',
69
+ highlight_pattern = f'{value}'
70
+ )
71
+ return self
72
+
73
+ matches = re.match(pattern, value)
74
+ d = matches.groupdict()
75
+ d = {k: int(v) for k,v in d.items() if v }
76
+ if 'millisecond' in d.keys():
77
+ ms = d.pop('millisecond')
78
+ d.update({'microsecond': ms * 1000})
79
+ try:
80
+ if d.get('year'): # input is only a time
81
+ datetime(**d)
82
+ else:
83
+ time(**d)
84
+ except ValueError:
85
+ self._add_validation_message(
86
+ source=f"TREX date value {value}",
87
+ level=ValidationMsgLevel.ERROR,
88
+ msg=f'{value} is no valid date or time.',
89
+ highlight_pattern = f'{value}'
90
+ )
91
+
92
+ self._date_time_dict = d
93
+ return self
94
+
95
+
96
+ class BoolValue(Value):
97
+
98
+ @model_validator(mode='after')
99
+ def _validate(self):
100
+ if self.value not in ['T', 'F']:
101
+ self._add_validation_message(
102
+ source=f"TREX boolean value {self.value}",
103
+ level= ValidationMsgLevel.ERROR,
104
+ msg=f'{self.value} is no valid boolean. Must be T or F',
105
+ highlight_pattern = f'{self.value}',
106
+ highlight_sub=[c for c in self.value]
107
+ )
108
+ return self
109
+
110
+
111
+ class AlphanumericValue(Value):
112
+
113
+ @model_validator(mode='after')
114
+ def _validate(self):
115
+ if re.match(r'[a-z]', self.value):
116
+ self._add_validation_message(
117
+ source=f"TREX value {self.value}",
118
+ level= ValidationMsgLevel.ERROR,
119
+ msg="Lower case characters are not allowed.",
120
+ highlight_pattern = self.value
121
+ )
122
+
123
+ if not_allowed_chars := set(re.sub(r'[A-Z0-9\.-]', '', self.value)):
124
+ self._add_validation_message(
125
+ source=f"TREX value {self.value}",
126
+ level= ValidationMsgLevel.ERROR,
127
+ msg=f"Characters {_quote_texts(not_allowed_chars)} are not allowed in alphanumeric segment",
128
+ highlight_pattern = self.value,
129
+ highlight_sub=not_allowed_chars
130
+ )
131
+ return self
132
+
133
+
134
+ class TextValue(Value):
135
+
136
+ @model_validator(mode='after')
137
+ def _validate(self):
138
+ if not_allowed_chars := set(re.sub(r'[A-Z0-9]', '', self.value)):
139
+ self._add_validation_message(
140
+ source=f"TREX value {self.value}",
141
+ level= ValidationMsgLevel.ERROR,
142
+ msg=f"Characters {_quote_texts(not_allowed_chars)} are not allowed in text segment. Base36 encoding only allows A-Z0-9",
143
+ highlight_pattern = self.value,
144
+ highlight_sub=not_allowed_chars
145
+ )
146
+ return self
147
+
148
+
149
+ class BinaryValue(Value):
150
+
151
+ @model_validator(mode='after')
152
+ def _validate(self):
153
+ if not_allowed_chars := set(re.sub(r'[A-Z0-9]', '', self.value)):
154
+ self._add_validation_message(
155
+ source=f"TREX value {self.value}",
156
+ level= ValidationMsgLevel.ERROR,
157
+ msg=f"Characters {_quote_texts(not_allowed_chars)} are not allowed in text segment. Base36 encoding only allows A-Z0-9",
158
+ highlight_pattern = self.value,
159
+ highlight_sub=not_allowed_chars
160
+ )
161
+ return self
162
+
163
+
164
+ class ErrorValue(Value):
165
+
166
+ @model_validator(mode='after')
167
+ def _validate(self):
168
+ if not_allowed_chars := set(re.sub(r'[A-Z0-9\.-]', '', self.value)):
169
+ self._add_validation_message(
170
+ source=f"TREX value {self.value}",
171
+ level= ValidationMsgLevel.ERROR,
172
+ msg=f"Characters {_quote_texts(not_allowed_chars)} are not allowed in error segment",
173
+ highlight_pattern = self.value,
174
+ highlight_sub=not_allowed_chars
175
+ )
176
+ return self
177
+
178
+
179
+ class TREX_Segment(LabFREED_BaseModel, ABC):
180
+ '''@private
181
+ Abstract class representing a TREX_Segment
182
+ '''
183
+ key: str
184
+
185
+ @abstractmethod
186
+ def serialize(self):
187
+ raise NotImplementedError("Subclasses must implement 'serialize_as_trex()' method")
188
+
189
+
190
+ @model_validator(mode='after')
191
+ def _validate_key(self):
192
+ if not_allowed_chars := set(re.sub(r'[A-Z0-9\.-]', '', self.key)):
193
+ self._add_validation_message(
194
+ source=f"TREX segment key {self.key}",
195
+ level=ValidationMsgLevel.ERROR,
196
+ msg=f"Segment key contains invalid characters: {_quote_texts(not_allowed_chars)}",
197
+ highlight_pattern = f'{self.key}$',
198
+ highlight_sub=not_allowed_chars
199
+ )
200
+ return self
201
+
202
+
203
+
204
+
205
+
206
+
207
+
208
+
209
+
@@ -1,99 +1,99 @@
1
- from abc import ABC
2
- import re
3
- from typing import Literal
4
- from pydantic import Field, model_validator
5
- from labfreed.well_known_keys.unece.unece_units import unece_unit_codes
6
- from labfreed.labfreed_infrastructure import ValidationMsgLevel
7
- from labfreed.trex.trex_base_models import AlphanumericValue, BinaryValue, BoolValue, DateValue, ErrorValue, NumericValue, TREX_Segment, TextValue, Value
8
-
9
-
10
-
11
- class ValueSegment(TREX_Segment, Value, ABC):
12
- '''@private: Abstract base class for value segments'''
13
- type:str
14
-
15
- @model_validator(mode='after')
16
- def _validate_type(self):
17
- valid_types = valid_types = unece_unit_codes() + ['T.D', 'T.B', 'T.A', 'T.T', 'T.X', 'E']
18
- if self.type not in valid_types:
19
- self._add_validation_message(
20
- source=f"TREX value segment {self.key}",
21
- level= ValidationMsgLevel.ERROR,
22
- msg=f"Type {self.type} is invalid. Must be 'T.D', 'T.B', 'T.A', 'T.T', 'T.X', 'E' or a UNECE unit",
23
- highlight_pattern = self.type
24
- )
25
- return self
26
-
27
-
28
- def serialize(self) -> str:
29
- return f'{self.key}${self.type}:{self.value}'
30
-
31
-
32
- class NumericSegment(ValueSegment, NumericValue):
33
- '''Represents a TREX segment holding a numeric value'''
34
- type: str
35
- key:str
36
- value:str
37
-
38
- class DateSegment(ValueSegment, DateValue):
39
- '''Represents a TREX segment holding a date'''
40
- type: Literal['T.D'] = Field('T.D', frozen=True)
41
- key:str
42
- value:str
43
-
44
- class BoolSegment(ValueSegment, BoolValue):
45
- '''Represents a TREX segment holding a boolean value'''
46
- type: Literal['T.B'] = Field('T.B', frozen=True)
47
- key:str
48
- value:str
49
- class AlphanumericSegment(ValueSegment, AlphanumericValue):
50
- '''Represents a TREX segment holding a alphanumeric text'''
51
- type: Literal['T.A'] = Field('T.A', frozen=True)
52
- key:str
53
- value:str
54
- class TextSegment(ValueSegment, TextValue):
55
- '''Represents a TREX segment holding a text with arbitrary characters'''
56
- type: Literal['T.T'] = Field('T.T', frozen=True)
57
- key:str
58
- value:str
59
-
60
- class BinarySegment(ValueSegment, BinaryValue):
61
- '''Represents a TREX segment holding binary data'''
62
- type: Literal['T.X'] = Field('T.X', frozen=True)
63
- key:str
64
- value:str
65
-
66
- class ErrorSegment(ValueSegment, ErrorValue):
67
- '''Represents a TREX segment which has erroneous content'''
68
- type: Literal['E'] = Field('E', frozen=True)
69
- key:str
70
- value:str
71
-
72
-
73
- def _deserialize_value_segment_from_trex_segment_str(trex_segment_str) -> ValueSegment:
74
- #re_scalar_pattern = re.compile(f"(?P<name>[\w\.-]*?)\$(?P<unit>[\w\.]*?):(?P<value>.*)")
75
- re_scalar_pattern = re.compile("(?P<name>.+?)\$(?P<unit>.+?):(?P<value>.+)")
76
- matches = re_scalar_pattern.match(trex_segment_str)
77
- if not matches:
78
- return None
79
-
80
- key, type_, value = matches.groups()
81
-
82
- match type_:
83
- case 'T.D':
84
- out = DateSegment(key=key, value=value, type=type_)
85
- case 'T.B':
86
- out = BoolSegment(key=key, value=value, type=type_)
87
- case 'T.A':
88
- out = AlphanumericSegment(key=key, value=value, type=type_)
89
- case 'T.T':
90
- out = TextSegment(key=key, value=value, type=type_)
91
- case 'T.X':
92
- out = BinarySegment(key=key, value=value, type=type_)
93
- case 'E':
94
- out = ErrorSegment(key=key, value=value, type=type_)
95
- case _:
96
- out = NumericSegment(value=value, key=key, type=type_)
97
-
98
- return out
99
-
1
+ from abc import ABC
2
+ import re
3
+ from typing import Literal
4
+ from pydantic import Field, model_validator
5
+ from labfreed.well_known_keys.unece.unece_units import unece_unit_codes
6
+ from labfreed.labfreed_infrastructure import ValidationMsgLevel
7
+ from labfreed.trex.trex_base_models import AlphanumericValue, BinaryValue, BoolValue, DateValue, ErrorValue, NumericValue, TREX_Segment, TextValue, Value
8
+
9
+
10
+
11
+ class ValueSegment(TREX_Segment, Value, ABC):
12
+ '''@private: Abstract base class for value segments'''
13
+ type:str
14
+
15
+ @model_validator(mode='after')
16
+ def _validate_type(self):
17
+ valid_types = valid_types = unece_unit_codes() + ['T.D', 'T.B', 'T.A', 'T.T', 'T.X', 'E']
18
+ if self.type not in valid_types:
19
+ self._add_validation_message(
20
+ source=f"TREX value segment {self.key}",
21
+ level= ValidationMsgLevel.ERROR,
22
+ msg=f"Type {self.type} is invalid. Must be 'T.D', 'T.B', 'T.A', 'T.T', 'T.X', 'E' or a UNECE unit",
23
+ highlight_pattern = self.type
24
+ )
25
+ return self
26
+
27
+
28
+ def serialize(self) -> str:
29
+ return f'{self.key}${self.type}:{self.value}'
30
+
31
+
32
+ class NumericSegment(ValueSegment, NumericValue):
33
+ '''Represents a TREX segment holding a numeric value'''
34
+ type: str
35
+ key:str
36
+ value:str
37
+
38
+ class DateSegment(ValueSegment, DateValue):
39
+ '''Represents a TREX segment holding a date'''
40
+ type: Literal['T.D'] = Field('T.D', frozen=True)
41
+ key:str
42
+ value:str
43
+
44
+ class BoolSegment(ValueSegment, BoolValue):
45
+ '''Represents a TREX segment holding a boolean value'''
46
+ type: Literal['T.B'] = Field('T.B', frozen=True)
47
+ key:str
48
+ value:str
49
+ class AlphanumericSegment(ValueSegment, AlphanumericValue):
50
+ '''Represents a TREX segment holding a alphanumeric text'''
51
+ type: Literal['T.A'] = Field('T.A', frozen=True)
52
+ key:str
53
+ value:str
54
+ class TextSegment(ValueSegment, TextValue):
55
+ '''Represents a TREX segment holding a text with arbitrary characters'''
56
+ type: Literal['T.T'] = Field('T.T', frozen=True)
57
+ key:str
58
+ value:str
59
+
60
+ class BinarySegment(ValueSegment, BinaryValue):
61
+ '''Represents a TREX segment holding binary data'''
62
+ type: Literal['T.X'] = Field('T.X', frozen=True)
63
+ key:str
64
+ value:str
65
+
66
+ class ErrorSegment(ValueSegment, ErrorValue):
67
+ '''Represents a TREX segment which has erroneous content'''
68
+ type: Literal['E'] = Field('E', frozen=True)
69
+ key:str
70
+ value:str
71
+
72
+
73
+ def _deserialize_value_segment_from_trex_segment_str(trex_segment_str) -> ValueSegment:
74
+ #re_scalar_pattern = re.compile(f"(?P<name>[\w\.-]*?)\$(?P<unit>[\w\.]*?):(?P<value>.*)")
75
+ re_scalar_pattern = re.compile("(?P<name>.+?)\$(?P<unit>.+?):(?P<value>.+)")
76
+ matches = re_scalar_pattern.match(trex_segment_str)
77
+ if not matches:
78
+ return None
79
+
80
+ key, type_, value = matches.groups()
81
+
82
+ match type_:
83
+ case 'T.D':
84
+ out = DateSegment(key=key, value=value, type=type_)
85
+ case 'T.B':
86
+ out = BoolSegment(key=key, value=value, type=type_)
87
+ case 'T.A':
88
+ out = AlphanumericSegment(key=key, value=value, type=type_)
89
+ case 'T.T':
90
+ out = TextSegment(key=key, value=value, type=type_)
91
+ case 'T.X':
92
+ out = BinarySegment(key=key, value=value, type=type_)
93
+ case 'E':
94
+ out = ErrorSegment(key=key, value=value, type=type_)
95
+ case _:
96
+ out = NumericSegment(value=value, key=key, type=type_)
97
+
98
+ return out
99
+