Source code for erc7730.convert.calldata.v1.enum

"""
Conversion of ERC-7730 enum definitions to calldata descriptor instructions.
"""

from erc7730.model.calldata.v1.instruction import (
    CalldataDescriptorInstructionEnumValueV1,
)
from erc7730.model.metadata import EnumDefinition
from erc7730.model.resolved.context import ResolvedDeployment
from erc7730.model.types import Id, Selector

# A bool holds 0 or 1 in calldata, and an enum key is the field value it matches, so these are
# the keys a descriptor writes for a bool field. JSON has no bool object key, so they arrive as
# text, and the casing follows whoever wrote the descriptor rather than any rule.
BOOLEAN_ORDINALS = {"true": 1, "false": 0}


[docs] def enum_ordinal(ordinal: str) -> int: """Value the device compares an enum entry against. :param ordinal: enum key, as written in the descriptor :return: the numeric field value it stands for :raises ValueError: if the key is neither decimal nor a boolean literal """ try: return int(ordinal) except ValueError: if (value := BOOLEAN_ORDINALS.get(ordinal.strip().lower())) is not None: return value raise
[docs] def convert_enums( deployment: ResolvedDeployment, selector: Selector, enums: dict[Id, EnumDefinition] | None ) -> list[CalldataDescriptorInstructionEnumValueV1]: """ Convert descriptor enum definitions to calldata descriptor enum value instructions. @param enums: descriptor enum definitions @return: instructions for each enum entry """ if enums is None: return [] return [ CalldataDescriptorInstructionEnumValueV1( chain_id=deployment.chainId, address=deployment.address, selector=selector, id=i, enum_id=enum_id, value=enum_ordinal(ordinal), name=name, ) for i, (enum_id, enum) in enumerate(enums.items()) for ordinal, name in enum.items() ]