66"""
77
88from enum import Enum
9- from typing import TYPE_CHECKING , Any , Generic , Literal , TypeVar , get_args , get_origin
9+ from typing import TYPE_CHECKING , Annotated , Generic , TypeVar
1010
11+ from annotated_types import doc
1112from pydantic .generics import GenericModel
1213
1314
@@ -29,34 +30,24 @@ def __str__(self) -> str: ...
2930 TField = TypeVar ("TField" , bound = str )
3031
3132
32- def get_literal_values (tfield : Any ) -> tuple [str , ...] | None :
33- """Return Literal values if TField is a Literal, else None."""
34- if get_origin (tfield ) is Literal :
35- return get_args (tfield )
36- return None
37-
38-
3933class OrderClause (GenericModel , Generic [TField ]):
4034 field : TField
4135 direction : OrderDirection = OrderDirection .ASC
4236
4337
4438def check_ordering_list (
45- order_by : list [tuple [TField , OrderDirection ]],
46- ) -> list [tuple [TField , OrderDirection ]]:
39+ order_by : Annotated [
40+ list [tuple [TField , OrderDirection ]],
41+ doc (
42+ "Duplicates with same direction dropped, conflicting directions raise ValueError"
43+ ),
44+ ],
45+ ) -> Annotated [
46+ list [tuple [TField , OrderDirection ]],
47+ doc ("Duplicates removed, preserving first occurrence order" ),
48+ ]:
4749 """Validates ordering list and removes duplicate entries.
4850
49- Ensures that each field appears at most once. If a field is repeated:
50- - With the same direction: silently drops the duplicate
51- - With different directions: raises ValueError
52-
53-
54- Args:
55- order_by: List of (field, direction) tuples
56-
57- Returns:
58- List with duplicates removed, preserving order of first occurrence
59-
6051 Raises:
6152 ValueError: If a field appears with conflicting directions
6253 """
@@ -77,55 +68,3 @@ def check_ordering_list(
7768 unique_order_by .append ((field , direction ))
7869
7970 return unique_order_by
80-
81-
82- def map_order_fields (
83- order_clauses : list [OrderClause [TField ]], field_mapping : dict [str , str ]
84- ) -> list [tuple [str , OrderDirection ]]:
85- """Map order clause fields using a field mapping dictionary.
86-
87- Args:
88- order_clauses: List of OrderClause objects with API field names
89- field_mapping: Dictionary mapping API field names to domain/DB field names
90-
91- Returns:
92- List of tuples with mapped field names and directions
93-
94- Example:
95- >>> clauses = [OrderClause(field="email", direction=OrderDirection.ASC)]
96- >>> mapping = {"email": "user_email", "created_at": "created"}
97- >>> map_order_fields(clauses, mapping)
98- [("user_email", OrderDirection.ASC)]
99- """
100- return [
101- (field_mapping [str (clause .field )], clause .direction ) for clause in order_clauses
102- ]
103-
104-
105- def validate_order_fields_with_literals (
106- order_by : list [tuple [str , str ]],
107- valid_fields : set [str ],
108- ) -> None :
109- """Validate order_by list with string field names and directions.
110-
111- Args:
112- order_by: List of (field_name, direction) tuples with string values
113- valid_fields: Set of allowed field names
114- valid_directions: Set of allowed direction values
115-
116- Raises:
117- ValueError: If any field or direction is invalid
118- """
119- valid_directions = {OrderDirection .ASC .value , OrderDirection .DESC .value }
120-
121- invalid_fields = {field for field , _ in order_by if field not in valid_fields }
122- if invalid_fields :
123- msg = f"Invalid order_by field(s): { invalid_fields } . Valid fields are: { valid_fields } "
124- raise ValueError (msg )
125-
126- invalid_directions = {
127- direction for _ , direction in order_by if direction not in valid_directions
128- }
129- if invalid_directions :
130- msg = f"Invalid order direction(s): { invalid_directions } . Must be one of: { valid_directions } "
131- raise ValueError (msg )
0 commit comments