Source code for remerkleable.basic

from typing import Any, TypeVar, Type
from remerkleable.core import BasicView, View

V = TypeVar('V', bound=View)


[docs]class boolean(int, BasicView):
[docs] def encode_bytes(self) -> bytes: return b"\x01" if self else b"\x00"
def __new__(cls, value: int): # int value, but can be any subclass of int (bool, Bit, Bool, etc...) if value < 0 or value > 1: raise ValueError(f"value {value} out of bounds for bit") return super().__new__(cls, value) def __bool__(self): return self > 0
[docs] @classmethod def coerce_view(cls: Type[V], v: Any) -> V: return cls(v)
[docs] @classmethod def type_byte_length(cls) -> int: return 1
[docs] @classmethod def decode_bytes(cls: Type[V], bytez: bytes) -> V: return cls(bytez != b"\x00")
[docs] @classmethod def type_repr(cls) -> str: return "boolean"
[docs]class uint(int, BasicView): def __new__(cls, value: int): if value < 0: raise ValueError(f"unsigned type {cls} must not be negative") byte_len = cls.type_byte_length() if value.bit_length() > (byte_len << 3): raise ValueError(f"value out of bounds for {cls}") return super().__new__(cls, value) def __add__(self, other): return self.__class__(super().__add__(self.__class__.coerce_view(other))) def __sub__(self, other): return self.__class__(super().__sub__(self.__class__.coerce_view(other)))
[docs] @classmethod def coerce_view(cls: Type[V], v: Any) -> V: if isinstance(v, uint) and cls.type_byte_length() != v.__class__.type_byte_length(): raise ValueError("value must have equal byte length to coerce it") if isinstance(v, bytes): return cls.decode_bytes(v) return cls(v)
[docs] @classmethod def decode_bytes(cls: Type[V], bytez: bytes) -> V: return cls(int.from_bytes(bytez, byteorder='little'))
[docs] def encode_bytes(self) -> bytes: return self.to_bytes(length=self.__class__.type_byte_length(), byteorder='little')
[docs] @classmethod def type_repr(cls) -> str: return f"uint{cls.type_byte_length()*8}"
[docs]class uint8(uint):
[docs] @classmethod def type_byte_length(cls) -> int: return 1
[docs]class uint16(uint):
[docs] @classmethod def type_byte_length(cls) -> int: return 2
[docs]class uint32(uint):
[docs] @classmethod def type_byte_length(cls) -> int: return 4
[docs]class uint64(uint):
[docs] @classmethod def type_byte_length(cls) -> int: return 8
[docs]class uint128(uint):
[docs] @classmethod def type_byte_length(cls) -> int: return 16
[docs]class uint256(uint):
[docs] @classmethod def type_byte_length(cls) -> int: return 32
[docs]class bit(boolean): pass
[docs]class byte(uint8): pass