feat: add ListField

This commit is contained in:
rus07tam 2025-11-26 14:02:48 +00:00
parent 2149fcf308
commit 7e8b57793f
3 changed files with 42 additions and 0 deletions

View file

@ -3,6 +3,7 @@ from .bool import BoolField
from .field import Field
from .float import FloatField
from .int import IntField
from .list import ListField
from .str import StrField
__all__ = [
@ -11,5 +12,6 @@ __all__ = [
"BoolField",
"FloatField",
"IntField",
"ListField",
"StrField",
]

38
src/snakia/field/list.py Normal file
View file

@ -0,0 +1,38 @@
from typing import Callable, Final, Iterable, TypeVar
from typing_extensions import Self
from .field import Field
T = TypeVar("T")
class ListField(Field[list[T]]):
def __init__(
self,
field: Field[T],
*,
length_size: int = 1,
default_factory: Callable[[Self], Iterable[T]] = lambda _: (),
) -> None:
self.length_size: Final[int] = length_size
self.field: Final = field
super().__init__(default_factory=lambda s: [*default_factory(s)])
def serialize(self, items: list[T], /) -> bytes:
result = b""
for item in items:
value = self.field.serialize(item)
length_prefix = len(value).to_bytes(self.length_size, "big")
result += length_prefix + value
return result
def deserialize(self, serialized: bytes, /) -> list[T]:
result = []
while serialized:
length = int.from_bytes(serialized[: self.length_size], "big")
serialized = serialized[self.length_size :]
item = self.field.deserialize(serialized[:length])
serialized = serialized[length:]
result.append(item)
return result

View file

@ -4,6 +4,7 @@ from .bool import BoolField as bool
from .field import Field as field
from .float import FloatField as float
from .int import IntField as int
from .list import ListField as list
from .str import StrField as str
__all__ = [
@ -12,5 +13,6 @@ __all__ = [
"field",
"float",
"int",
"list",
"str",
]