Skip to main content

icydb_core/db/response/
paged.rs

1//! Module: response::paged
2//! Responsibility: paged load response payload contracts.
3//! Does not own: query execution, pagination planning, or cursor token protocol.
4//! Boundary: response DTOs returned by session/query execution APIs.
5
6use crate::{
7    db::{
8        diagnostics::{ExecutionMetrics, ExecutionTrace},
9        query::read_intent::ReadIntentKind,
10        response::{EntityResponse, Row},
11    },
12    traits::EntityKind,
13};
14
15///
16/// PagedLoadExecution
17///
18/// Cursor-paged load response with optional continuation cursor bytes.
19///
20
21#[derive(Debug)]
22pub struct PagedLoadExecution<E: EntityKind> {
23    response: EntityResponse<E>,
24    continuation_cursor: Option<Vec<u8>>,
25    read_intent: ReadIntentKind,
26}
27
28impl<E: EntityKind> PagedLoadExecution<E> {
29    /// Borrow the paged response rows.
30    #[must_use]
31    pub const fn response(&self) -> &EntityResponse<E> {
32        &self.response
33    }
34
35    /// Borrow an iterator over paged rows in response order.
36    pub fn iter(&self) -> std::slice::Iter<'_, Row<E>> {
37        self.response.iter()
38    }
39
40    /// Borrow the optional continuation cursor bytes.
41    #[must_use]
42    pub fn continuation_cursor(&self) -> Option<&[u8]> {
43        self.continuation_cursor.as_deref()
44    }
45
46    /// Return diagnostic read-intent metadata for this paged execution.
47    ///
48    /// This is reporting metadata only. It does not configure admission,
49    /// planning, cursor encoding, or execution semantics.
50    #[must_use]
51    pub const fn read_intent(&self) -> ReadIntentKind {
52        self.read_intent
53    }
54
55    /// Attach diagnostic read-intent metadata.
56    #[must_use]
57    pub(in crate::db) const fn with_read_intent(mut self, read_intent: ReadIntentKind) -> Self {
58        self.read_intent = read_intent;
59        self
60    }
61
62    /// Consume this payload and return response rows plus continuation cursor.
63    #[must_use]
64    pub fn into_response_and_cursor(self) -> (EntityResponse<E>, Option<Vec<u8>>) {
65        (self.response, self.continuation_cursor)
66    }
67}
68
69impl<'a, E: EntityKind> IntoIterator for &'a PagedLoadExecution<E> {
70    type Item = &'a Row<E>;
71    type IntoIter = std::slice::Iter<'a, Row<E>>;
72
73    fn into_iter(self) -> Self::IntoIter {
74        self.iter()
75    }
76}
77
78///
79/// PagedLoadExecutionWithTrace
80///
81/// Cursor-paged load response plus optional execution trace details.
82///
83
84#[derive(Debug)]
85pub struct PagedLoadExecutionWithTrace<E: EntityKind> {
86    response: EntityResponse<E>,
87    continuation_cursor: Option<Vec<u8>>,
88    execution_trace: Option<ExecutionTrace>,
89    read_intent: ReadIntentKind,
90}
91
92impl<E: EntityKind> PagedLoadExecutionWithTrace<E> {
93    /// Create a traced paged load execution payload.
94    #[must_use]
95    pub(in crate::db) const fn new(
96        response: EntityResponse<E>,
97        continuation_cursor: Option<Vec<u8>>,
98        execution_trace: Option<ExecutionTrace>,
99    ) -> Self {
100        Self {
101            response,
102            continuation_cursor,
103            execution_trace,
104            read_intent: ReadIntentKind::Unspecified,
105        }
106    }
107
108    /// Borrow the paged response rows.
109    #[must_use]
110    pub const fn response(&self) -> &EntityResponse<E> {
111        &self.response
112    }
113
114    /// Borrow an iterator over paged rows in response order.
115    pub fn iter(&self) -> std::slice::Iter<'_, Row<E>> {
116        self.response.iter()
117    }
118
119    /// Borrow the optional continuation cursor bytes.
120    #[must_use]
121    pub fn continuation_cursor(&self) -> Option<&[u8]> {
122        self.continuation_cursor.as_deref()
123    }
124
125    /// Borrow optional execution trace details.
126    #[must_use]
127    pub const fn execution_trace(&self) -> Option<&ExecutionTrace> {
128        self.execution_trace.as_ref()
129    }
130
131    /// Borrow compact execution metrics derived from the optional execution trace.
132    #[must_use]
133    pub fn execution_metrics(&self) -> Option<ExecutionMetrics> {
134        self.execution_trace.as_ref().map(ExecutionTrace::metrics)
135    }
136
137    /// Return diagnostic read-intent metadata for this paged execution.
138    ///
139    /// This is reporting metadata only. It does not configure admission,
140    /// planning, cursor encoding, or execution semantics.
141    #[must_use]
142    pub const fn read_intent(&self) -> ReadIntentKind {
143        self.read_intent
144    }
145
146    /// Attach diagnostic read-intent metadata.
147    #[must_use]
148    pub(in crate::db) const fn with_read_intent(mut self, read_intent: ReadIntentKind) -> Self {
149        self.read_intent = read_intent;
150        self
151    }
152
153    /// Consume this payload and drop trace details.
154    #[must_use]
155    pub fn into_execution(self) -> PagedLoadExecution<E> {
156        PagedLoadExecution {
157            response: self.response,
158            continuation_cursor: self.continuation_cursor,
159            read_intent: self.read_intent,
160        }
161    }
162
163    /// Consume this payload and return response rows, continuation cursor, and trace.
164    #[must_use]
165    pub fn into_response_cursor_and_trace(
166        self,
167    ) -> (EntityResponse<E>, Option<Vec<u8>>, Option<ExecutionTrace>) {
168        (
169            self.response,
170            self.continuation_cursor,
171            self.execution_trace,
172        )
173    }
174}
175
176impl<'a, E: EntityKind> IntoIterator for &'a PagedLoadExecutionWithTrace<E> {
177    type Item = &'a Row<E>;
178    type IntoIter = std::slice::Iter<'a, Row<E>>;
179
180    fn into_iter(self) -> Self::IntoIter {
181        self.iter()
182    }
183}