diff --git a/src/snakia/field/__init__.py b/src/snakia/field/__init__.py index 752b06e..e95ce46 100644 --- a/src/snakia/field/__init__.py +++ b/src/snakia/field/__init__.py @@ -4,6 +4,7 @@ from .field import Field from .float import FloatField from .int import IntField from .list import ListField +from .optional import OptionalField from .str import StrField __all__ = [ @@ -13,5 +14,6 @@ __all__ = [ "FloatField", "IntField", "ListField", + "OptionalField", "StrField", ] diff --git a/src/snakia/field/optional.py b/src/snakia/field/optional.py new file mode 100644 index 0000000..eb437c0 --- /dev/null +++ b/src/snakia/field/optional.py @@ -0,0 +1,28 @@ +from typing import Final, TypeVar + +from .field import Field + +T = TypeVar("T") + + +class OptionalField(Field[T | None]): + + def __init__( + self, + field: Field[T], + *, + none_value: bytes = b"", + ) -> None: + super().__init__(None) + self.none_value: Final = none_value + self.field: Final = field + + def serialize(self, value: T | None, /) -> bytes: + if value is None: + return self.none_value + return self.field.serialize(value) + + def deserialize(self, serialized: bytes, /) -> T | None: + if serialized == self.none_value: + return None + return self.field.deserialize(serialized) diff --git a/src/snakia/field/t.py b/src/snakia/field/t.py index 64cf5a7..abb404b 100644 --- a/src/snakia/field/t.py +++ b/src/snakia/field/t.py @@ -5,6 +5,7 @@ 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 .optional import OptionalField as optional from .str import StrField as str __all__ = [ @@ -14,5 +15,6 @@ __all__ = [ "float", "int", "list", + "optional", "str", ]