1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
//! Typed `OData` query builder - re-exported from `modkit-odata`
//!
//! This module re-exports the canonical `OData` query building functionality from `modkit-odata`,
//! along with SDK-specific streaming utilities for cursor-based pagination.
//!
//! The SDK re-exports the canonical `QueryBuilder` from `modkit-odata`.
//! Streaming adapters are provided as free functions `pages_stream` and `items_stream`.
//!
//! # Example
//!
//! ```rust,ignore
//! use modkit_sdk::odata::{items_stream, pages_stream, FieldRef, QueryBuilder, Schema};
//! use modkit_odata::SortDir;
//!
//! #[derive(Copy, Clone, Eq, PartialEq)]
//! enum UserField {
//! Id,
//! Name,
//! Email,
//! }
//!
//! struct UserSchema;
//!
//! impl Schema for UserSchema {
//! type Field = UserField;
//!
//! fn field_name(field: Self::Field) -> &'static str {
//! match field {
//! UserField::Id => "id",
//! UserField::Name => "name",
//! UserField::Email => "email",
//! }
//! }
//! }
//!
//! // Define typed field references
//! const ID: FieldRef<UserSchema, uuid::Uuid> = FieldRef::new(UserField::Id);
//! const NAME: FieldRef<UserSchema, String> = FieldRef::new(UserField::Name);
//!
//! // Build a query
//! let user_id = uuid::Uuid::new_v4();
//! let query = QueryBuilder::<UserSchema>::new()
//! .filter(ID.eq(user_id).and(NAME.contains("john")))
//! .order_by(NAME, SortDir::Asc)
//! .page_size(50)
//! .build();
//!
//! // Stream pages
//! let pages = pages_stream(
//! QueryBuilder::<UserSchema>::new()
//! .filter(ID.eq(user_id).and(NAME.contains("john")))
//! .page_size(50),
//! |q| async move { client.list_users(q).await },
//! );
//!
//! // Stream items
//! let items = items_stream(
//! QueryBuilder::<UserSchema>::new()
//! .filter(ID.eq(user_id).and(NAME.contains("john")))
//! .page_size(50),
//! |q| async move { client.list_users(q).await },
//! );
//! ```
pub use ODataQuery;
// Re-export core OData types from modkit-odata (the canonical source)
pub use QueryBuilder;
pub use ;
use Future;
use Pin;
/// Boxed future for `OData` page fetchers.
pub type BoxedODataFuture<'a, T, E> =
;
/// Boxed fetcher for `OData` pagination (accepts an `ODataQuery` and returns a boxed future).
pub type BoxedODataFetcher<'a, T, E> =
;
/// Named stream type produced by `items_stream` when using boxed fetchers.
pub type ItemsStream<'a, T, E> =
crateCursorPager;
/// Create a stream of pages using cursor pagination.
///
/// This consumes the builder, builds `ODataQuery`, then returns a `PagesPager`.
/// Create a stream of items using cursor pagination.
///
/// This consumes the builder, builds `ODataQuery`, then returns a `CursorPager`.
/// Create a boxed stream of pages using cursor pagination.
///
/// This helper mirrors `pages_stream` but accepts a boxed fetcher and returns the boxed pager type.
///
/// # Example
/// ```rust,ignore
/// use modkit_sdk::odata::{pages_stream_boxed, QueryBuilder};
/// use std::pin::Pin;
///
/// let stream = pages_stream_boxed(
/// QueryBuilder::<UserSchema>::new().page_size(50),
/// Box::new(|q| Box::pin(async move { service.list_users_page(&ctx, &q).await })),
/// );
/// ```
/// Create a boxed stream of items using cursor pagination.
///
/// This helper mirrors `items_stream` but accepts a boxed fetcher and returns the named `ItemsStream` alias.
///
/// # Example
/// ```rust,ignore
/// use modkit_sdk::odata::{items_stream_boxed, QueryBuilder};
///
/// let stream = items_stream_boxed(
/// QueryBuilder::<UserSchema>::new().page_size(50),
/// Box::new(|q| Box::pin(async move { service.list_users_page(&ctx, &q).await })),
/// );
/// ```