Source code for hs_py.filter.ast
"""Filter expression AST node types.
Defines the abstract syntax tree produced by the filter parser.
Each node is a frozen dataclass for immutability and pattern matching.
See: https://project-haystack.org/doc/docHaystack/Filters
"""
from __future__ import annotations
from dataclasses import dataclass
from enum import Enum
from typing import Any
__all__ = [
"And",
"Cmp",
"CmpOp",
"Has",
"Missing",
"Node",
"Or",
"Path",
]
[docs]
class CmpOp(Enum):
"""Comparison operators for filter expressions."""
EQ = "=="
"""Equal (``==``)."""
NE = "!="
"""Not equal (``!=``)."""
LT = "<"
"""Less than (``<``)."""
LE = "<="
"""Less than or equal (``<=``)."""
GT = ">"
"""Greater than (``>``)."""
GE = ">="
"""Greater than or equal (``>=``)."""
[docs]
@dataclass(frozen=True, slots=True)
class Path:
"""Tag path expression (e.g. ``equipRef->siteRef->dis``).
Single-segment paths contain one name. Multi-segment paths use the
``->`` dereference operator to navigate through Ref-valued tags.
"""
names: tuple[str, ...]
"""Ordered path segments (at least one)."""
def __post_init__(self) -> None:
if not self.names:
raise ValueError("Path must have at least one name segment")
def __str__(self) -> str:
return "->".join(self.names)
[docs]
@dataclass(frozen=True, slots=True)
class Has:
"""Tag existence check (``path``)."""
path: Path
"""Tag path to test for presence."""
[docs]
@dataclass(frozen=True, slots=True)
class Missing:
"""Tag absence check (``not path``)."""
path: Path
"""Tag path to test for absence."""
[docs]
@dataclass(frozen=True, slots=True)
class Cmp:
"""Comparison of a tag path to a literal value."""
path: Path
"""Left-hand tag path."""
op: CmpOp
"""Comparison operator."""
val: Any
"""Right-hand literal value."""
[docs]
@dataclass(frozen=True, slots=True)
class And:
"""Logical AND of two filter nodes."""
left: Node
"""Left operand."""
right: Node
"""Right operand."""
[docs]
@dataclass(frozen=True, slots=True)
class Or:
"""Logical OR of two filter nodes."""
left: Node
"""Left operand."""
right: Node
"""Right operand."""
#: Union of all filter AST node types.
Node = Has | Missing | Cmp | And | Or