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    /// Consume this payload and return response rows plus continuation cursor.
56    #[must_use]
57    pub fn into_response_and_cursor(self) -> (EntityResponse<E>, Option<Vec<u8>>) {
58        (self.response, self.continuation_cursor)
59    }
60}
61
62impl<'a, E: EntityKind> IntoIterator for &'a PagedLoadExecution<E> {
63    type Item = &'a Row<E>;
64    type IntoIter = std::slice::Iter<'a, Row<E>>;
65
66    fn into_iter(self) -> Self::IntoIter {
67        self.iter()
68    }
69}
70
71///
72/// PagedLoadExecutionWithTrace
73///
74/// Cursor-paged load response plus optional execution trace details.
75///
76
77#[derive(Debug)]
78pub struct PagedLoadExecutionWithTrace<E: EntityKind> {
79    response: EntityResponse<E>,
80    continuation_cursor: Option<Vec<u8>>,
81    execution_trace: Option<ExecutionTrace>,
82    read_intent: ReadIntentKind,
83}
84
85impl<E: EntityKind> PagedLoadExecutionWithTrace<E> {
86    /// Create a traced paged load execution payload.
87    #[must_use]
88    pub(in crate::db) const fn new(
89        response: EntityResponse<E>,
90        continuation_cursor: Option<Vec<u8>>,
91        execution_trace: Option<ExecutionTrace>,
92    ) -> Self {
93        Self {
94            response,
95            continuation_cursor,
96            execution_trace,
97            read_intent: ReadIntentKind::Unspecified,
98        }
99    }
100
101    /// Borrow the paged response rows.
102    #[must_use]
103    pub const fn response(&self) -> &EntityResponse<E> {
104        &self.response
105    }
106
107    /// Borrow an iterator over paged rows in response order.
108    pub fn iter(&self) -> std::slice::Iter<'_, Row<E>> {
109        self.response.iter()
110    }
111
112    /// Borrow the optional continuation cursor bytes.
113    #[must_use]
114    pub fn continuation_cursor(&self) -> Option<&[u8]> {
115        self.continuation_cursor.as_deref()
116    }
117
118    /// Borrow optional execution trace details.
119    #[must_use]
120    pub const fn execution_trace(&self) -> Option<&ExecutionTrace> {
121        self.execution_trace.as_ref()
122    }
123
124    /// Borrow compact execution metrics derived from the optional execution trace.
125    #[must_use]
126    pub fn execution_metrics(&self) -> Option<ExecutionMetrics> {
127        self.execution_trace.as_ref().map(ExecutionTrace::metrics)
128    }
129
130    /// Return diagnostic read-intent metadata for this paged execution.
131    ///
132    /// This is reporting metadata only. It does not configure admission,
133    /// planning, cursor encoding, or execution semantics.
134    #[must_use]
135    pub const fn read_intent(&self) -> ReadIntentKind {
136        self.read_intent
137    }
138
139    /// Attach diagnostic read-intent metadata.
140    #[must_use]
141    pub(in crate::db) const fn with_read_intent(mut self, read_intent: ReadIntentKind) -> Self {
142        self.read_intent = read_intent;
143        self
144    }
145
146    /// Consume this payload and drop trace details.
147    #[must_use]
148    pub fn into_execution(self) -> PagedLoadExecution<E> {
149        PagedLoadExecution {
150            response: self.response,
151            continuation_cursor: self.continuation_cursor,
152            read_intent: self.read_intent,
153        }
154    }
155
156    /// Consume this payload and return response rows, continuation cursor, and trace.
157    #[must_use]
158    pub fn into_response_cursor_and_trace(
159        self,
160    ) -> (EntityResponse<E>, Option<Vec<u8>>, Option<ExecutionTrace>) {
161        (
162            self.response,
163            self.continuation_cursor,
164            self.execution_trace,
165        )
166    }
167}
168
169impl<'a, E: EntityKind> IntoIterator for &'a PagedLoadExecutionWithTrace<E> {
170    type Item = &'a Row<E>;
171    type IntoIter = std::slice::Iter<'a, Row<E>>;
172
173    fn into_iter(self) -> Self::IntoIter {
174        self.iter()
175    }
176}