tsrkit-types 0.1.0__tar.gz → 0.1.2__tar.gz
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.
- {tsrkit_types-0.1.0 → tsrkit_types-0.1.2}/CHANGELOG.md +3 -3
- {tsrkit_types-0.1.0 → tsrkit_types-0.1.2}/PKG-INFO +38 -49
- {tsrkit_types-0.1.0 → tsrkit_types-0.1.2}/README.md +34 -46
- {tsrkit_types-0.1.0 → tsrkit_types-0.1.2}/pyproject.toml +4 -3
- {tsrkit_types-0.1.0 → tsrkit_types-0.1.2}/tests/test_containers.py +74 -74
- {tsrkit_types-0.1.0 → tsrkit_types-0.1.2}/tests/test_int.py +1 -1
- {tsrkit_types-0.1.0 → tsrkit_types-0.1.2}/tests/test_integers.py +29 -29
- {tsrkit_types-0.1.0 → tsrkit_types-0.1.2}/tests/test_network.py +25 -18
- {tsrkit_types-0.1.0 → tsrkit_types-0.1.2}/tests/test_seq.py +19 -19
- {tsrkit_types-0.1.0 → tsrkit_types-0.1.2}/tests/test_struct.py +6 -6
- {tsrkit_types-0.1.0 → tsrkit_types-0.1.2}/tests/test_structs.py +63 -60
- {tsrkit_types-0.1.0 → tsrkit_types-0.1.2}/tsrkit_types/bytes.py +3 -5
- {tsrkit_types-0.1.0 → tsrkit_types-0.1.2}/tsrkit_types/choice.py +8 -3
- {tsrkit_types-0.1.0 → tsrkit_types-0.1.2}/tsrkit_types/dictionary.py +3 -2
- {tsrkit_types-0.1.0 → tsrkit_types-0.1.2}/tsrkit_types/enum.py +3 -3
- {tsrkit_types-0.1.0 → tsrkit_types-0.1.2}/tsrkit_types/null.py +3 -3
- {tsrkit_types-0.1.0 → tsrkit_types-0.1.2}/tsrkit_types/sequences.py +1 -1
- {tsrkit_types-0.1.0 → tsrkit_types-0.1.2}/tsrkit_types/struct.py +6 -2
- {tsrkit_types-0.1.0 → tsrkit_types-0.1.2}/tsrkit_types.egg-info/PKG-INFO +38 -49
- {tsrkit_types-0.1.0 → tsrkit_types-0.1.2}/CONTRIBUTING.md +0 -0
- {tsrkit_types-0.1.0 → tsrkit_types-0.1.2}/LICENSE +0 -0
- {tsrkit_types-0.1.0 → tsrkit_types-0.1.2}/MANIFEST.in +0 -0
- {tsrkit_types-0.1.0 → tsrkit_types-0.1.2}/pytest.ini +0 -0
- {tsrkit_types-0.1.0 → tsrkit_types-0.1.2}/setup.cfg +0 -0
- {tsrkit_types-0.1.0 → tsrkit_types-0.1.2}/setup.py +0 -0
- {tsrkit_types-0.1.0 → tsrkit_types-0.1.2}/tests/test_bytes.py +0 -0
- {tsrkit_types-0.1.0 → tsrkit_types-0.1.2}/tests/test_choices.py +0 -0
- {tsrkit_types-0.1.0 → tsrkit_types-0.1.2}/tests/test_enums.py +0 -0
- {tsrkit_types-0.1.0 → tsrkit_types-0.1.2}/tests/test_strings.py +0 -0
- {tsrkit_types-0.1.0 → tsrkit_types-0.1.2}/tsrkit_types/__init__.py +0 -0
- {tsrkit_types-0.1.0 → tsrkit_types-0.1.2}/tsrkit_types/bits.py +0 -0
- {tsrkit_types-0.1.0 → tsrkit_types-0.1.2}/tsrkit_types/bool.py +0 -0
- {tsrkit_types-0.1.0 → tsrkit_types-0.1.2}/tsrkit_types/integers.py +0 -0
- {tsrkit_types-0.1.0 → tsrkit_types-0.1.2}/tsrkit_types/itf/codable.py +0 -0
- {tsrkit_types-0.1.0 → tsrkit_types-0.1.2}/tsrkit_types/option.py +0 -0
- {tsrkit_types-0.1.0 → tsrkit_types-0.1.2}/tsrkit_types/string.py +0 -0
- {tsrkit_types-0.1.0 → tsrkit_types-0.1.2}/tsrkit_types.egg-info/SOURCES.txt +0 -0
- {tsrkit_types-0.1.0 → tsrkit_types-0.1.2}/tsrkit_types.egg-info/dependency_links.txt +0 -0
- {tsrkit_types-0.1.0 → tsrkit_types-0.1.2}/tsrkit_types.egg-info/requires.txt +0 -0
- {tsrkit_types-0.1.0 → tsrkit_types-0.1.2}/tsrkit_types.egg-info/top_level.txt +0 -0
|
@@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
-
## [0.1.0] -
|
|
8
|
+
## [0.1.0] - 2025-06-03
|
|
9
9
|
|
|
10
10
|
### Added
|
|
11
11
|
- Initial release of tsrkit-types library
|
|
@@ -20,7 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
20
20
|
- Dictionary type: `Dictionary[K, V]` with typed keys and values
|
|
21
21
|
- Bytes types: `Bytes` for raw binary data and `BitArray` for bit sequences
|
|
22
22
|
- Enumeration type: `Enum` with integer backing and string names
|
|
23
|
-
- Structured types: `@
|
|
23
|
+
- Structured types: `@structure` decorator for automatic `Codable` implementation
|
|
24
24
|
- Binary serialization with efficient encoding formats
|
|
25
25
|
- JSON serialization with customizable field mapping
|
|
26
26
|
- Type safety with runtime validation
|
|
@@ -35,7 +35,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
35
35
|
- Type validation at construction and assignment time
|
|
36
36
|
- Support for nested and complex type compositions
|
|
37
37
|
- Zero-dependency core library
|
|
38
|
-
- Python 3.
|
|
38
|
+
- Python 3.11+ support
|
|
39
39
|
|
|
40
40
|
## [Unreleased]
|
|
41
41
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tsrkit-types
|
|
3
|
-
Version: 0.1.
|
|
4
|
-
Summary:
|
|
3
|
+
Version: 0.1.2
|
|
4
|
+
Summary: Performant Python Typings library for type-safe binary serialization, JSON encoding, and data validation with zero dependencies
|
|
5
5
|
Author-email: chainscore-labs <hello@chainscore.finance>, prasad-kumkar <prasad@chainscore.finance>
|
|
6
6
|
License-Expression: MIT
|
|
7
7
|
Project-URL: Homepage, https://github.com/chainscore/tsrkit-types
|
|
@@ -15,6 +15,7 @@ Classifier: Intended Audience :: Developers
|
|
|
15
15
|
Classifier: Intended Audience :: System Administrators
|
|
16
16
|
Classifier: Operating System :: OS Independent
|
|
17
17
|
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
19
|
Classifier: Programming Language :: Python :: 3.12
|
|
19
20
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
20
21
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
@@ -26,7 +27,7 @@ Classifier: Topic :: Utilities
|
|
|
26
27
|
Classifier: Topic :: System :: Archiving
|
|
27
28
|
Classifier: Topic :: Communications
|
|
28
29
|
Classifier: Typing :: Typed
|
|
29
|
-
Requires-Python: >=3.
|
|
30
|
+
Requires-Python: >=3.11
|
|
30
31
|
Description-Content-Type: text/markdown
|
|
31
32
|
License-File: LICENSE
|
|
32
33
|
Provides-Extra: dev
|
|
@@ -40,7 +41,7 @@ Dynamic: license-file
|
|
|
40
41
|
|
|
41
42
|
# TSRKit Types
|
|
42
43
|
|
|
43
|
-
Performant Python library for type-safe binary serialization, JSON encoding, and data validation with zero dependencies.
|
|
44
|
+
Performant Python Typings library for type-safe binary serialization, JSON encoding, and data validation with zero dependencies.
|
|
44
45
|
|
|
45
46
|
Perfect for network protocols, game state serialization, configuration files, and any application requiring efficient, validated data handling.
|
|
46
47
|
|
|
@@ -62,7 +63,7 @@ pip install tsrkit-types
|
|
|
62
63
|
|
|
63
64
|
## Type Categories
|
|
64
65
|
|
|
65
|
-
### Integer Types
|
|
66
|
+
### Integer Types (extension of Python int)
|
|
66
67
|
|
|
67
68
|
#### Unsigned Integers (`Uint`)
|
|
68
69
|
|
|
@@ -70,13 +71,13 @@ The `Uint` class provides both fixed-size and variable-size unsigned integers.
|
|
|
70
71
|
|
|
71
72
|
**Fixed-Size Integers:**
|
|
72
73
|
```python
|
|
73
|
-
from tsrkit_types.integers import Uint
|
|
74
|
+
from tsrkit_types.integers import Uint
|
|
74
75
|
|
|
75
76
|
# Pre-defined types
|
|
76
|
-
value =
|
|
77
|
-
value =
|
|
78
|
-
value =
|
|
79
|
-
value =
|
|
77
|
+
value = Uint[8](255) # 8-bit unsigned integer (0-255)
|
|
78
|
+
value = Uint[16](65535) # 16-bit unsigned integer (0-65535)
|
|
79
|
+
value = Uint[32](42949) # 32-bit unsigned integer
|
|
80
|
+
value = Uint[64](1844674) # 64-bit unsigned integer
|
|
80
81
|
|
|
81
82
|
# Dynamic size specification
|
|
82
83
|
U128 = Uint[128] # 128-bit unsigned integer
|
|
@@ -96,9 +97,9 @@ encoded = num.encode()
|
|
|
96
97
|
decoded = Uint.decode(encoded)
|
|
97
98
|
|
|
98
99
|
# Arithmetic operations preserve type
|
|
99
|
-
a =
|
|
100
|
-
b =
|
|
101
|
-
result = a + b # result is
|
|
100
|
+
a = Uint[8](10)
|
|
101
|
+
b = Uint[8](20)
|
|
102
|
+
result = a + b # result is Uint[8](30)
|
|
102
103
|
```
|
|
103
104
|
|
|
104
105
|
**Encoding Details:**
|
|
@@ -107,7 +108,7 @@ result = a + b # result is U8(30)
|
|
|
107
108
|
- Values < 2^7 are encoded in 1 byte
|
|
108
109
|
- Larger values use a variable-length prefix encoding
|
|
109
110
|
|
|
110
|
-
### String Types
|
|
111
|
+
### String Types (extension of Python str)
|
|
111
112
|
|
|
112
113
|
#### UTF-8 Strings (`String`)
|
|
113
114
|
|
|
@@ -161,27 +162,11 @@ restored = Bool.from_json("true")
|
|
|
161
162
|
|
|
162
163
|
### Null Types
|
|
163
164
|
|
|
164
|
-
#### Null and Nullable
|
|
165
|
-
|
|
166
165
|
```python
|
|
167
|
-
from tsrkit_types.null import Null
|
|
166
|
+
from tsrkit_types.null import Null
|
|
168
167
|
|
|
169
168
|
# Null type
|
|
170
169
|
null_val = Null # Singleton null value
|
|
171
|
-
|
|
172
|
-
# Nullable wrapper for optional values
|
|
173
|
-
maybe_string = Nullable[String](String("hello"))
|
|
174
|
-
empty_val = Nullable[String]() # Contains null
|
|
175
|
-
|
|
176
|
-
# Check for null
|
|
177
|
-
if maybe_string.is_null():
|
|
178
|
-
print("Value is null")
|
|
179
|
-
else:
|
|
180
|
-
value = maybe_string.unwrap() # Get the wrapped value
|
|
181
|
-
|
|
182
|
-
# Encoding
|
|
183
|
-
encoded = maybe_string.encode() # 1 byte flag + optional value
|
|
184
|
-
decoded = Nullable[String].decode(encoded)
|
|
185
170
|
```
|
|
186
171
|
|
|
187
172
|
### Choice and Option Types
|
|
@@ -219,7 +204,7 @@ encoded = result.encode() # [variant_index][value]
|
|
|
219
204
|
decoded = Result.decode(encoded)
|
|
220
205
|
```
|
|
221
206
|
|
|
222
|
-
#### Option (Optional
|
|
207
|
+
#### Option (Optional Value - T | Null)
|
|
223
208
|
|
|
224
209
|
```python
|
|
225
210
|
from tsrkit_types.option import Option
|
|
@@ -240,7 +225,7 @@ decoded = Option[U32].decode(encoded)
|
|
|
240
225
|
|
|
241
226
|
### Container Types
|
|
242
227
|
|
|
243
|
-
#### Sequences (
|
|
228
|
+
#### Sequences (Extension of Python list)
|
|
244
229
|
|
|
245
230
|
```python
|
|
246
231
|
from tsrkit_types.sequences import Array, Vector, TypedArray, TypedVector
|
|
@@ -274,7 +259,7 @@ decoded = TypedDynamicVector.decode(encoded)
|
|
|
274
259
|
|
|
275
260
|
**Sequence Types:**
|
|
276
261
|
- `Array[N]`: Fixed size, any element type
|
|
277
|
-
- `Vector
|
|
262
|
+
- `Vector`: Variable size, any element type
|
|
278
263
|
- `TypedArray[T, N]`: Fixed size with typed elements
|
|
279
264
|
- `TypedVector[T]`: Variable size with typed elements
|
|
280
265
|
- `BoundedVector[min, max]`: Size constrained vector
|
|
@@ -314,7 +299,7 @@ restored = StringToInt.from_json(json_data)
|
|
|
314
299
|
|
|
315
300
|
### Bytes Types
|
|
316
301
|
|
|
317
|
-
####
|
|
302
|
+
#### Bytes (extension of Python in-built bytes)
|
|
318
303
|
|
|
319
304
|
```python
|
|
320
305
|
from tsrkit_types.bytes import Bytes
|
|
@@ -323,6 +308,10 @@ from tsrkit_types.bytes import Bytes
|
|
|
323
308
|
data = Bytes(b"Hello, binary world!")
|
|
324
309
|
data = Bytes([0x01, 0x02, 0x03, 0x04])
|
|
325
310
|
|
|
311
|
+
# Bytes <-> Bits Operations
|
|
312
|
+
data.to_bits() # [True, False, True, ...]
|
|
313
|
+
Bytes.from_bits([True, False, True, ...])
|
|
314
|
+
|
|
326
315
|
# Operations
|
|
327
316
|
length = len(data) # Byte length
|
|
328
317
|
raw_bytes = bytes(data) # Convert to Python bytes
|
|
@@ -336,7 +325,7 @@ json_str = data.to_json() # "48656c6c6f2c2062696e61727920776f726c6421"
|
|
|
336
325
|
restored = Bytes.from_json(json_str)
|
|
337
326
|
```
|
|
338
327
|
|
|
339
|
-
#### Bit Arrays
|
|
328
|
+
#### Bit Arrays (Sequence of bool)
|
|
340
329
|
|
|
341
330
|
```python
|
|
342
331
|
from tsrkit_types.bits import BitArray
|
|
@@ -361,7 +350,7 @@ encoded = bits.encode() # [length][packed_bits]
|
|
|
361
350
|
decoded = BitArray.decode(encoded)
|
|
362
351
|
```
|
|
363
352
|
|
|
364
|
-
###
|
|
353
|
+
### Enum (Extension of Python Enum, with Codable + JSON support)
|
|
365
354
|
|
|
366
355
|
```python
|
|
367
356
|
from tsrkit_types.enum import Enum
|
|
@@ -391,7 +380,7 @@ restored = Color.from_json("GREEN")
|
|
|
391
380
|
|
|
392
381
|
### Structured Types
|
|
393
382
|
|
|
394
|
-
#### Struct Decorator
|
|
383
|
+
#### Struct Decorator (Extension of dataclasses)
|
|
395
384
|
|
|
396
385
|
```python
|
|
397
386
|
from tsrkit_types.struct import struct
|
|
@@ -399,12 +388,12 @@ from tsrkit_types.string import String
|
|
|
399
388
|
from tsrkit_types.integers import U8, U32
|
|
400
389
|
from dataclasses import field
|
|
401
390
|
|
|
402
|
-
@
|
|
391
|
+
@structure
|
|
403
392
|
class Person:
|
|
404
393
|
name: String
|
|
405
394
|
age: U8
|
|
406
395
|
|
|
407
|
-
@
|
|
396
|
+
@structure
|
|
408
397
|
class Employee:
|
|
409
398
|
person: Person
|
|
410
399
|
employee_id: U32
|
|
@@ -427,7 +416,7 @@ encoded = employee.encode() # Concatenated field encodings
|
|
|
427
416
|
decoded = Employee.decode(encoded)
|
|
428
417
|
|
|
429
418
|
# JSON serialization with custom field names
|
|
430
|
-
@
|
|
419
|
+
@structure
|
|
431
420
|
class CustomPerson:
|
|
432
421
|
name: String = field(metadata={"name": "full_name"})
|
|
433
422
|
age: U8
|
|
@@ -479,7 +468,7 @@ class Point3D(Codable):
|
|
|
479
468
|
|
|
480
469
|
```python
|
|
481
470
|
# Optimize for specific use cases
|
|
482
|
-
@
|
|
471
|
+
@structure(frozen=True) # Immutable structs
|
|
483
472
|
class ImmutableData:
|
|
484
473
|
value: U64
|
|
485
474
|
|
|
@@ -575,8 +564,8 @@ offset += value2.encode_into(buffer, offset)
|
|
|
575
564
|
|
|
576
565
|
### Network Protocol
|
|
577
566
|
|
|
578
|
-
|
|
579
|
-
@
|
|
567
|
+
```**python**
|
|
568
|
+
@structure
|
|
580
569
|
class NetworkPacket:
|
|
581
570
|
packet_type: U8
|
|
582
571
|
session_id: U32
|
|
@@ -601,7 +590,7 @@ received_packet = NetworkPacket.decode(wire_data)
|
|
|
601
590
|
### Configuration File
|
|
602
591
|
|
|
603
592
|
```python
|
|
604
|
-
@
|
|
593
|
+
@structure
|
|
605
594
|
class DatabaseConfig:
|
|
606
595
|
host: String
|
|
607
596
|
port: U16
|
|
@@ -637,19 +626,19 @@ class GameEntityType(Enum):
|
|
|
637
626
|
ENEMY = 1
|
|
638
627
|
ITEM = 2
|
|
639
628
|
|
|
640
|
-
@
|
|
629
|
+
@structure
|
|
641
630
|
class Position:
|
|
642
631
|
x: U16
|
|
643
632
|
y: U16
|
|
644
633
|
|
|
645
|
-
@
|
|
634
|
+
@structure
|
|
646
635
|
class GameEntity:
|
|
647
636
|
entity_type: GameEntityType
|
|
648
637
|
position: Position
|
|
649
638
|
health: U8
|
|
650
639
|
name: String
|
|
651
640
|
|
|
652
|
-
@
|
|
641
|
+
@structure
|
|
653
642
|
class GameState:
|
|
654
643
|
level: U8
|
|
655
644
|
score: U32
|
|
@@ -745,6 +734,6 @@ Contributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for gui
|
|
|
745
734
|
|
|
746
735
|
## Requirements
|
|
747
736
|
|
|
748
|
-
- **Python**: >= 3.
|
|
737
|
+
- **Python**: >= 3.11
|
|
749
738
|
- **Runtime Dependencies**: None (zero dependencies!)
|
|
750
739
|
- **Development Dependencies**: pytest and plugins (see `pyproject.toml`)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# TSRKit Types
|
|
2
2
|
|
|
3
|
-
Performant Python library for type-safe binary serialization, JSON encoding, and data validation with zero dependencies.
|
|
3
|
+
Performant Python Typings library for type-safe binary serialization, JSON encoding, and data validation with zero dependencies.
|
|
4
4
|
|
|
5
5
|
Perfect for network protocols, game state serialization, configuration files, and any application requiring efficient, validated data handling.
|
|
6
6
|
|
|
@@ -22,7 +22,7 @@ pip install tsrkit-types
|
|
|
22
22
|
|
|
23
23
|
## Type Categories
|
|
24
24
|
|
|
25
|
-
### Integer Types
|
|
25
|
+
### Integer Types (extension of Python int)
|
|
26
26
|
|
|
27
27
|
#### Unsigned Integers (`Uint`)
|
|
28
28
|
|
|
@@ -30,13 +30,13 @@ The `Uint` class provides both fixed-size and variable-size unsigned integers.
|
|
|
30
30
|
|
|
31
31
|
**Fixed-Size Integers:**
|
|
32
32
|
```python
|
|
33
|
-
from tsrkit_types.integers import Uint
|
|
33
|
+
from tsrkit_types.integers import Uint
|
|
34
34
|
|
|
35
35
|
# Pre-defined types
|
|
36
|
-
value =
|
|
37
|
-
value =
|
|
38
|
-
value =
|
|
39
|
-
value =
|
|
36
|
+
value = Uint[8](255) # 8-bit unsigned integer (0-255)
|
|
37
|
+
value = Uint[16](65535) # 16-bit unsigned integer (0-65535)
|
|
38
|
+
value = Uint[32](42949) # 32-bit unsigned integer
|
|
39
|
+
value = Uint[64](1844674) # 64-bit unsigned integer
|
|
40
40
|
|
|
41
41
|
# Dynamic size specification
|
|
42
42
|
U128 = Uint[128] # 128-bit unsigned integer
|
|
@@ -56,9 +56,9 @@ encoded = num.encode()
|
|
|
56
56
|
decoded = Uint.decode(encoded)
|
|
57
57
|
|
|
58
58
|
# Arithmetic operations preserve type
|
|
59
|
-
a =
|
|
60
|
-
b =
|
|
61
|
-
result = a + b # result is
|
|
59
|
+
a = Uint[8](10)
|
|
60
|
+
b = Uint[8](20)
|
|
61
|
+
result = a + b # result is Uint[8](30)
|
|
62
62
|
```
|
|
63
63
|
|
|
64
64
|
**Encoding Details:**
|
|
@@ -67,7 +67,7 @@ result = a + b # result is U8(30)
|
|
|
67
67
|
- Values < 2^7 are encoded in 1 byte
|
|
68
68
|
- Larger values use a variable-length prefix encoding
|
|
69
69
|
|
|
70
|
-
### String Types
|
|
70
|
+
### String Types (extension of Python str)
|
|
71
71
|
|
|
72
72
|
#### UTF-8 Strings (`String`)
|
|
73
73
|
|
|
@@ -121,27 +121,11 @@ restored = Bool.from_json("true")
|
|
|
121
121
|
|
|
122
122
|
### Null Types
|
|
123
123
|
|
|
124
|
-
#### Null and Nullable
|
|
125
|
-
|
|
126
124
|
```python
|
|
127
|
-
from tsrkit_types.null import Null
|
|
125
|
+
from tsrkit_types.null import Null
|
|
128
126
|
|
|
129
127
|
# Null type
|
|
130
128
|
null_val = Null # Singleton null value
|
|
131
|
-
|
|
132
|
-
# Nullable wrapper for optional values
|
|
133
|
-
maybe_string = Nullable[String](String("hello"))
|
|
134
|
-
empty_val = Nullable[String]() # Contains null
|
|
135
|
-
|
|
136
|
-
# Check for null
|
|
137
|
-
if maybe_string.is_null():
|
|
138
|
-
print("Value is null")
|
|
139
|
-
else:
|
|
140
|
-
value = maybe_string.unwrap() # Get the wrapped value
|
|
141
|
-
|
|
142
|
-
# Encoding
|
|
143
|
-
encoded = maybe_string.encode() # 1 byte flag + optional value
|
|
144
|
-
decoded = Nullable[String].decode(encoded)
|
|
145
129
|
```
|
|
146
130
|
|
|
147
131
|
### Choice and Option Types
|
|
@@ -179,7 +163,7 @@ encoded = result.encode() # [variant_index][value]
|
|
|
179
163
|
decoded = Result.decode(encoded)
|
|
180
164
|
```
|
|
181
165
|
|
|
182
|
-
#### Option (Optional
|
|
166
|
+
#### Option (Optional Value - T | Null)
|
|
183
167
|
|
|
184
168
|
```python
|
|
185
169
|
from tsrkit_types.option import Option
|
|
@@ -200,7 +184,7 @@ decoded = Option[U32].decode(encoded)
|
|
|
200
184
|
|
|
201
185
|
### Container Types
|
|
202
186
|
|
|
203
|
-
#### Sequences (
|
|
187
|
+
#### Sequences (Extension of Python list)
|
|
204
188
|
|
|
205
189
|
```python
|
|
206
190
|
from tsrkit_types.sequences import Array, Vector, TypedArray, TypedVector
|
|
@@ -234,7 +218,7 @@ decoded = TypedDynamicVector.decode(encoded)
|
|
|
234
218
|
|
|
235
219
|
**Sequence Types:**
|
|
236
220
|
- `Array[N]`: Fixed size, any element type
|
|
237
|
-
- `Vector
|
|
221
|
+
- `Vector`: Variable size, any element type
|
|
238
222
|
- `TypedArray[T, N]`: Fixed size with typed elements
|
|
239
223
|
- `TypedVector[T]`: Variable size with typed elements
|
|
240
224
|
- `BoundedVector[min, max]`: Size constrained vector
|
|
@@ -274,7 +258,7 @@ restored = StringToInt.from_json(json_data)
|
|
|
274
258
|
|
|
275
259
|
### Bytes Types
|
|
276
260
|
|
|
277
|
-
####
|
|
261
|
+
#### Bytes (extension of Python in-built bytes)
|
|
278
262
|
|
|
279
263
|
```python
|
|
280
264
|
from tsrkit_types.bytes import Bytes
|
|
@@ -283,6 +267,10 @@ from tsrkit_types.bytes import Bytes
|
|
|
283
267
|
data = Bytes(b"Hello, binary world!")
|
|
284
268
|
data = Bytes([0x01, 0x02, 0x03, 0x04])
|
|
285
269
|
|
|
270
|
+
# Bytes <-> Bits Operations
|
|
271
|
+
data.to_bits() # [True, False, True, ...]
|
|
272
|
+
Bytes.from_bits([True, False, True, ...])
|
|
273
|
+
|
|
286
274
|
# Operations
|
|
287
275
|
length = len(data) # Byte length
|
|
288
276
|
raw_bytes = bytes(data) # Convert to Python bytes
|
|
@@ -296,7 +284,7 @@ json_str = data.to_json() # "48656c6c6f2c2062696e61727920776f726c6421"
|
|
|
296
284
|
restored = Bytes.from_json(json_str)
|
|
297
285
|
```
|
|
298
286
|
|
|
299
|
-
#### Bit Arrays
|
|
287
|
+
#### Bit Arrays (Sequence of bool)
|
|
300
288
|
|
|
301
289
|
```python
|
|
302
290
|
from tsrkit_types.bits import BitArray
|
|
@@ -321,7 +309,7 @@ encoded = bits.encode() # [length][packed_bits]
|
|
|
321
309
|
decoded = BitArray.decode(encoded)
|
|
322
310
|
```
|
|
323
311
|
|
|
324
|
-
###
|
|
312
|
+
### Enum (Extension of Python Enum, with Codable + JSON support)
|
|
325
313
|
|
|
326
314
|
```python
|
|
327
315
|
from tsrkit_types.enum import Enum
|
|
@@ -351,7 +339,7 @@ restored = Color.from_json("GREEN")
|
|
|
351
339
|
|
|
352
340
|
### Structured Types
|
|
353
341
|
|
|
354
|
-
#### Struct Decorator
|
|
342
|
+
#### Struct Decorator (Extension of dataclasses)
|
|
355
343
|
|
|
356
344
|
```python
|
|
357
345
|
from tsrkit_types.struct import struct
|
|
@@ -359,12 +347,12 @@ from tsrkit_types.string import String
|
|
|
359
347
|
from tsrkit_types.integers import U8, U32
|
|
360
348
|
from dataclasses import field
|
|
361
349
|
|
|
362
|
-
@
|
|
350
|
+
@structure
|
|
363
351
|
class Person:
|
|
364
352
|
name: String
|
|
365
353
|
age: U8
|
|
366
354
|
|
|
367
|
-
@
|
|
355
|
+
@structure
|
|
368
356
|
class Employee:
|
|
369
357
|
person: Person
|
|
370
358
|
employee_id: U32
|
|
@@ -387,7 +375,7 @@ encoded = employee.encode() # Concatenated field encodings
|
|
|
387
375
|
decoded = Employee.decode(encoded)
|
|
388
376
|
|
|
389
377
|
# JSON serialization with custom field names
|
|
390
|
-
@
|
|
378
|
+
@structure
|
|
391
379
|
class CustomPerson:
|
|
392
380
|
name: String = field(metadata={"name": "full_name"})
|
|
393
381
|
age: U8
|
|
@@ -439,7 +427,7 @@ class Point3D(Codable):
|
|
|
439
427
|
|
|
440
428
|
```python
|
|
441
429
|
# Optimize for specific use cases
|
|
442
|
-
@
|
|
430
|
+
@structure(frozen=True) # Immutable structs
|
|
443
431
|
class ImmutableData:
|
|
444
432
|
value: U64
|
|
445
433
|
|
|
@@ -535,8 +523,8 @@ offset += value2.encode_into(buffer, offset)
|
|
|
535
523
|
|
|
536
524
|
### Network Protocol
|
|
537
525
|
|
|
538
|
-
|
|
539
|
-
@
|
|
526
|
+
```**python**
|
|
527
|
+
@structure
|
|
540
528
|
class NetworkPacket:
|
|
541
529
|
packet_type: U8
|
|
542
530
|
session_id: U32
|
|
@@ -561,7 +549,7 @@ received_packet = NetworkPacket.decode(wire_data)
|
|
|
561
549
|
### Configuration File
|
|
562
550
|
|
|
563
551
|
```python
|
|
564
|
-
@
|
|
552
|
+
@structure
|
|
565
553
|
class DatabaseConfig:
|
|
566
554
|
host: String
|
|
567
555
|
port: U16
|
|
@@ -597,19 +585,19 @@ class GameEntityType(Enum):
|
|
|
597
585
|
ENEMY = 1
|
|
598
586
|
ITEM = 2
|
|
599
587
|
|
|
600
|
-
@
|
|
588
|
+
@structure
|
|
601
589
|
class Position:
|
|
602
590
|
x: U16
|
|
603
591
|
y: U16
|
|
604
592
|
|
|
605
|
-
@
|
|
593
|
+
@structure
|
|
606
594
|
class GameEntity:
|
|
607
595
|
entity_type: GameEntityType
|
|
608
596
|
position: Position
|
|
609
597
|
health: U8
|
|
610
598
|
name: String
|
|
611
599
|
|
|
612
|
-
@
|
|
600
|
+
@structure
|
|
613
601
|
class GameState:
|
|
614
602
|
level: U8
|
|
615
603
|
score: U32
|
|
@@ -705,6 +693,6 @@ Contributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for gui
|
|
|
705
693
|
|
|
706
694
|
## Requirements
|
|
707
695
|
|
|
708
|
-
- **Python**: >= 3.
|
|
696
|
+
- **Python**: >= 3.11
|
|
709
697
|
- **Runtime Dependencies**: None (zero dependencies!)
|
|
710
698
|
- **Development Dependencies**: pytest and plugins (see `pyproject.toml`)
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "tsrkit-types"
|
|
3
|
-
version = "0.1.
|
|
4
|
-
description = "
|
|
3
|
+
version = "0.1.2"
|
|
4
|
+
description = "Performant Python Typings library for type-safe binary serialization, JSON encoding, and data validation with zero dependencies"
|
|
5
5
|
authors = [
|
|
6
6
|
{name = "chainscore-labs", email = "hello@chainscore.finance"},
|
|
7
7
|
{name = "prasad-kumkar", email = "prasad@chainscore.finance"}
|
|
8
8
|
]
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "MIT"
|
|
11
|
-
requires-python = ">=3.
|
|
11
|
+
requires-python = ">=3.11"
|
|
12
12
|
keywords = [
|
|
13
13
|
"serialization", "binary", "encoding", "types", "codable", "json",
|
|
14
14
|
"validation", "data-types", "type-safety", "zero-copy", "protocol",
|
|
@@ -20,6 +20,7 @@ classifiers = [
|
|
|
20
20
|
"Intended Audience :: System Administrators",
|
|
21
21
|
"Operating System :: OS Independent",
|
|
22
22
|
"Programming Language :: Python :: 3",
|
|
23
|
+
"Programming Language :: Python :: 3.11",
|
|
23
24
|
"Programming Language :: Python :: 3.12",
|
|
24
25
|
"Programming Language :: Python :: 3 :: Only",
|
|
25
26
|
"Topic :: Software Development :: Libraries :: Python Modules",
|