diff --git a/src/kat_transform/metadata.py b/src/kat_transform/metadata.py index eaf5767..117357e 100644 --- a/src/kat_transform/metadata.py +++ b/src/kat_transform/metadata.py @@ -1,4 +1,33 @@ -class FieldMetadata: +import typing + +T = typing.TypeVar("T", bound="Metadata") + + +class Metadata: + def __init__(self) -> None: + self.entries: tuple[Metadata, ...] = (self,) + + def get_metadata(self, metadata_type: type[T], exact: bool = False) -> T | None: + for entry in self.entries: + if type(entry) is metadata_type: + return entry + + if not exact and isinstance(entry, metadata_type): + return entry + + return None + + def __or__(self, other: "Metadata") -> "CombinedMetadata": + return CombinedMetadata(*self.entries, *other.entries) + + +class CombinedMetadata(Metadata): + def __init__(self, *entries: Metadata): + super().__init__() + self.entries: tuple[Metadata, ...] = entries + + +class FieldMetadata(Metadata): """ Field metadata that can be used by other tools (like json schema generation) @@ -6,7 +35,7 @@ class FieldMetadata: """ -class SchemaMetadata: +class SchemaMetadata(Metadata): """ Schema metadata that can be used by other tools (like json schema generation) diff --git a/tests/test_metadata.py b/tests/test_metadata.py new file mode 100644 index 0000000..d419bc6 --- /dev/null +++ b/tests/test_metadata.py @@ -0,0 +1,16 @@ +from kat_transform.metadata import Metadata + + +def test_combination(): + class CustomMeta(Metadata): ... + + custom = CustomMeta() + empty = Metadata() + + combined = custom | empty + assert combined.entries == (custom, empty) + + assert combined.get_metadata(CustomMeta) is custom + + assert combined.get_metadata(Metadata) is custom + assert combined.get_metadata(Metadata, exact=True) is empty