Source code for dag.ipld_model
"""IPLD Data Model - the universal representation layer.
The IPLD Data Model defines the following *kinds* of values that can
appear in any IPLD node:
Null, Bool, Int, Float, String, Bytes, List, Map, Link
A *Link* is a CID (Content IDentifier) that points to another block.
This module provides:
- ``Kind`` enum for type discrimination
- Helper predicates for checking values
- Type alias ``IPLDNode`` for type-annotated IPLD data
Reference: https://ipld.io/docs/data-model/
"""
from __future__ import annotations
import enum
from typing import Any, Union
from cid import CIDv0, CIDv1
[docs]
class Kind(enum.Enum):
"""IPLD Data Model kinds.
Every value in the IPLD Data Model belongs to exactly one kind.
"""
NULL = "null"
BOOL = "bool"
INT = "int"
FLOAT = "float"
STRING = "string"
BYTES = "bytes"
LIST = "list"
MAP = "map"
LINK = "link"
CID = Union[CIDv0, CIDv1]
"""A Content IDentifier - either CIDv0 or CIDv1."""
IPLDNode = Union[
None,
bool,
int,
float,
str,
bytes,
list["IPLDNode"],
dict[str, "IPLDNode"],
CID,
]
"""Any value conforming to the IPLD Data Model.
- ``None`` → Null
- ``bool`` → Bool
- ``int`` → Int
- ``float`` → Float
- ``str`` → String
- ``bytes`` → Bytes
- ``list`` → List
- ``dict`` → Map (keys must be strings)
- ``CID`` → Link
"""
[docs]
def kind_of(value: Any) -> Kind:
"""Return the IPLD ``Kind`` of *value*.
Raises ``TypeError`` if the value is not representable in the IPLD
Data Model.
"""
if value is None:
return Kind.NULL
if isinstance(value, bool):
return Kind.BOOL
if isinstance(value, int):
return Kind.INT
if isinstance(value, float):
return Kind.FLOAT
if isinstance(value, str):
return Kind.STRING
if isinstance(value, (bytes, bytearray)):
return Kind.BYTES
if isinstance(value, (CIDv0, CIDv1)):
return Kind.LINK
if isinstance(value, list):
return Kind.LIST
if isinstance(value, dict):
return Kind.MAP
raise TypeError(f"Value {value!r} ({type(value).__name__}) is not an IPLD kind")
[docs]
def is_cid(value: Any) -> bool:
"""Return ``True`` if *value* is a CID (IPLD Link)."""
return isinstance(value, (CIDv0, CIDv1))
[docs]
def is_ipld_value(value: Any) -> bool:
"""Return ``True`` if *value* is representable in the IPLD Data Model."""
try:
kind_of(value)
return True
except TypeError:
return False