Source code for jam.types.base.choices.option

from typing import Any, Dict, Tuple, Type, Union
from jam.types.base.choices.choice import Choice
from jam.types.base.null import Null, Nullable
from jam.utils.codec.codable import Codable
from jam.utils.codec.composite.choices import ChoiceCodec


[docs] class Option(Choice): """ An option is a choice that can be either None or a value. """ def __init_subclass__(cls, **kwargs): ...
[docs] def __init__(self, initial: Codable = Null): super().__init__(Option.option_to_choice(initial))
[docs] @staticmethod def option_to_choice(value: Codable | Nullable) -> Dict[str, Codable]: if value is None or isinstance(value, Nullable): return {"none": Null} else: return {"some": value}
def __set__(self, value: Codable | Nullable): super().__set__(Option.option_to_choice(value))
[docs] @classmethod def from_json(cls, data: Any) -> "Option": """Create from JSON representation.""" if data is None: return cls(Nullable()) value = cls.__choices__["some"].from_json(data) print("option from json", value) return cls(value)
[docs] def to_json(self) -> Any: """Convert to JSON representation.""" if isinstance(self.value, Nullable) or self.value is None: return None return list(self.value.values())[0].to_json()
def __eq__(self, other: Any) -> bool: if isinstance(other, Option): return self.value == other.value return list(self.value.values())[0] == other def __repr__(self) -> str: return f"{self.__class__.__name__}({list(self.value.values())[0]})"
[docs] def decodable_option(optional_type: Type[Codable]) -> Type[Option]: """Decodable choice""" def decorator(cls: Type[Option]) -> Type[Option]: cls.__choices__ = {"none": Nullable, "some": optional_type} @staticmethod def decode_from( buffer: Union[bytes, bytearray, memoryview], offset: int = 0 ) -> Tuple[Option, int]: """ Decode option from buffer. Args: optional_type: Type of the optional value buffer: Source buffer offset: Starting offset Returns: Tuple of (decoded value, bytes read) Raises: DecodeError: If buffer is invalid or too short ValueError: If types list is empty """ if len(cls.__choices__) == 0: raise ValueError("Choice must have at least one type") value, size = ChoiceCodec.decode_from(cls.__choices__, buffer, offset) return cls(list(value.values())[0]), size cls.decode_from = decode_from return cls return decorator