Source code for runtimepy.enum.registry
"""
A module implementing and enumeration registry.
"""
# built-in
from enum import IntEnum as _IntEnum
from typing import Optional as _Optional
from typing import TypeVar
from typing import Union as _Union
from typing import cast as _cast
# third-party
from vcorelib.io.types import JsonObject as _JsonObject
# internal
from runtimepy.enum import RuntimeEnum as _RuntimeEnum
from runtimepy.enum.types import EnumTypelike as _EnumTypelike
from runtimepy.mapping import EnumMappingData as _EnumMappingData
from runtimepy.registry import Registry as _Registry
DEFAULT_ENUM_PRIMITIVE = "uint8"
[docs]
class EnumRegistry(_Registry[_RuntimeEnum]):
"""A runtime enumeration registry."""
@property
def kind(self) -> type[_RuntimeEnum]:
"""Determine what kind of registry this is."""
return _RuntimeEnum
[docs]
def enum(
self,
name: str,
kind: _EnumTypelike,
items: _EnumMappingData = None,
primitive: str = DEFAULT_ENUM_PRIMITIVE,
default: _Union[str, bool, int] = None,
) -> _Optional[_RuntimeEnum]:
"""Create a new runtime enumeration."""
data: _JsonObject = {"type": _cast(str, kind), "primitive": primitive}
if items is not None:
data["items"] = items # type: ignore
if default is not None:
data["default"] = default
return self.register_dict(name, data)
T = TypeVar("T", bound="RuntimeIntEnum")
[docs]
class RuntimeIntEnum(_IntEnum):
"""An integer enumeration extension."""
[docs]
@classmethod
def normalize(cls: type[T], data: int | str | T) -> T:
"""
Normalize a value at runtime that is either integer, string or an enum
instance.
"""
if isinstance(data, int):
data = cls(data)
elif isinstance(data, str):
data = cls[data.upper()]
return data
[docs]
@classmethod
def id(cls) -> _Optional[int]:
"""Override in sub-class to coerce enum id."""
return None
[docs]
@classmethod
def default(cls: type[T]) -> _Optional[T]:
"""Get a possible default value for this enumeration."""
return None
[docs]
@classmethod
def primitive(cls) -> str:
"""The underlying primitive type for this runtime enumeration."""
return DEFAULT_ENUM_PRIMITIVE
[docs]
@classmethod
def enum_name(cls) -> str:
"""Get a name for this enumeration."""
return cls.__name__
[docs]
@classmethod
def runtime_enum(cls, identifier: int) -> _RuntimeEnum:
"""Obtain a runtime enumeration from this class."""
return _RuntimeEnum.from_enum(cls, identifier, default=cls.default())
[docs]
@classmethod
def register_enum(
cls, registry: EnumRegistry, name: str = None
) -> _RuntimeEnum:
"""Register an enumeration to a registry."""
if name is None:
name = cls.enum_name()
data = _RuntimeEnum.data_from_enum(cls)
data["primitive"] = cls.primitive()
ident = cls.id()
if ident is not None:
data["id"] = ident
if cls.default() is not None:
data["default"] = cls.default()
result = registry.register_dict(name, data)
assert result is not None, (name, data)
return result