from __future__ import annotations from .shared import * def _enum_value(value: Any) -> Any: return value.value if hasattr(value, "value") else value def _parse_role_values(raw: Any) -> list[str]: if raw is None: return [] if isinstance(raw, (list, tuple, set)): values = [str(_enum_value(item)).strip().upper() for item in raw] else: values = [str(token).strip().upper() for token in str(_enum_value(raw)).split(",")] deduped: list[str] = [] for value in values: if value and value not in deduped: deduped.append(value) return deduped def _normalize_role_input(raw: Any, *, allow_empty: bool = False) -> list[str]: values = _parse_role_values(raw) if not values and not allow_empty: raise ValueError("role required") invalid = [value for value in values if value not in VALID_ROLE_VALUES] if invalid: raise ValueError(f"Invalid role: {','.join(invalid)}") return values def _pack_roles(raw: Any) -> str: return ",".join(_normalize_role_input(raw)) def _has_any_role(raw: Any, *roles: str) -> bool: values = set(_parse_role_values(raw)) expected = {str(role).strip().upper() for role in roles} return bool(values.intersection(expected)) def _build_role_filter(column: Any, roles: list[str]) -> Any: filters = [] for role in roles: filters.extend( [ column == role, column.like(f"{role},%"), column.like(f"%,{role},%"), column.like(f"%,{role}"), ] ) return or_(*filters) def _parse_int_list(raw: Optional[str]) -> list[int]: if not raw: return [] ids: list[int] = [] for part in raw.split(","): token = part.strip() if not token: continue try: ids.append(int(token)) except ValueError: continue return ids