Source code for haive.core.utils.getter_mixin

"""Collection utilities for Haive Core - GetterMixin.

This module includes powerful retrieval and filtering utilities
for collection classes.
"""

from collections.abc import Callable
from typing import Any, Generic, TypeVar

T = TypeVar("T")


[docs] class GetterMixin(Generic[T]): """A mixin providing rich lookup and filtering capabilities for collections. This mixin can be added to any collection class that implements _get_items() to provide powerful querying capabilities. """ def _get_items(self) -> list[T]: """Get all items from the collection. Must be implemented by subclasses. """ raise NotImplementedError("Subclasses must implement _get_items()")
[docs] def get_by_attr( self, attr_name: str, value: Any, default: T | None = None ) -> T | None: """Get first item where attribute equals value. Args: attr_name: Attribute name to check value: Value to match default: Default value if not found Returns: First matching item or default """ for item in self._get_items(): if self._has_attr_value(item, attr_name, value): return item return default
[docs] def get_all_by_attr(self, attr_name: str, value: Any) -> list[T]: """Get all items where attribute equals value. Args: attr_name: Attribute name to check value: Value to match Returns: List of matching items """ return [ item for item in self._get_items() if self._has_attr_value(item, attr_name, value) ]
[docs] def filter(self, **kwargs) -> list[T]: """Filter items by multiple attribute criteria. Args: **kwargs: Field name and value pairs to match Returns: List of matching items """ results = [] for item in self._get_items(): match = True for attr, value in kwargs.items(): if not self._has_attr_value(item, attr, value): match = False break if match: results.append(item) return results
[docs] def find(self, predicate: Callable[[T], bool]) -> T | None: """Find first item matching a custom predicate function. Args: predicate: Function that takes item and returns boolean Returns: First matching item or None """ for item in self._get_items(): if predicate(item): return item return None
[docs] def find_all(self, predicate: Callable[[T], bool]) -> list[T]: """Find all items matching a custom predicate function. Args: predicate: Function that takes item and returns boolean Returns: List of matching items """ return [item for item in self._get_items() if predicate(item)]
[docs] def get_by_type(self, type_cls: type) -> list[T]: """Get all items of specified type. Args: type_cls: Type to match Returns: List of matching items """ return [item for item in self._get_items() if isinstance(item, type_cls)]
[docs] def field_values(self, field_name: str) -> list[Any]: """Get all values for a specific field across items. Args: field_name: Field name to collect Returns: List of field values """ results = [] for item in self._get_items(): if isinstance(item, dict) and field_name in item: results.append(item[field_name]) elif hasattr(item, field_name): value = getattr(item, field_name) results.append(value) else: results.append(None) return results
[docs] def first(self, **kwargs) -> T | None: """Get first item matching criteria. Args: **kwargs: Field name and value pairs to match Returns: First matching item or None """ results = self.filter(**kwargs) return results[0] if results else None
def _has_attr_value(self, item: Any, attr: str, value: Any) -> bool: """Check if item has attribute with specified value. Args: item: Item to check attr: Attribute name value: Value to match Returns: True if attribute matches value """ if isinstance(item, dict): return attr in item and item[attr] == value return hasattr(item, attr) and getattr(item, attr) == value