Skip to main content

icydb_core/db/response/
grouped.rs

1//! Module: response::grouped
2//! Responsibility: grouped paged response payload contracts.
3//! Does not own: grouped execution evaluation, route policy, or cursor token protocol.
4//! Boundary: grouped DTOs returned by session/query execution APIs.
5
6use crate::{db::diagnostics::ExecutionTrace, value::Value};
7
8///
9/// GroupedRow
10///
11/// One grouped result row: ordered grouping key values plus ordered aggregate outputs.
12/// Group/aggregate vectors preserve query declaration order.
13///
14
15#[derive(Clone, Debug, Eq, PartialEq)]
16pub struct GroupedRow {
17    group_key: Vec<Value>,
18    aggregate_values: Vec<Value>,
19}
20
21impl GroupedRow {
22    /// Construct one grouped row payload.
23    #[must_use]
24    pub const fn new(group_key: Vec<Value>, aggregate_values: Vec<Value>) -> Self {
25        Self {
26            group_key,
27            aggregate_values,
28        }
29    }
30
31    #[must_use]
32    pub fn from_parts<I, J>(group_key: I, aggregate_values: J) -> Self
33    where
34        I: IntoIterator<Item = Value>,
35        J: IntoIterator<Item = Value>,
36    {
37        Self {
38            group_key: group_key.into_iter().collect(),
39            aggregate_values: aggregate_values.into_iter().collect(),
40        }
41    }
42
43    /// Borrow grouped key values.
44    #[must_use]
45    pub const fn group_key(&self) -> &[Value] {
46        self.group_key.as_slice()
47    }
48
49    /// Borrow aggregate output values.
50    #[must_use]
51    pub const fn aggregate_values(&self) -> &[Value] {
52        self.aggregate_values.as_slice()
53    }
54}
55
56///
57/// PagedGroupedExecution
58///
59/// Cursor-paged grouped execution payload with optional continuation cursor bytes.
60///
61
62#[derive(Clone, Debug)]
63pub struct PagedGroupedExecution {
64    rows: Vec<GroupedRow>,
65    continuation_cursor: Option<Vec<u8>>,
66}
67
68impl PagedGroupedExecution {
69    /// Construct one grouped paged execution payload.
70    #[must_use]
71    pub const fn new(rows: Vec<GroupedRow>, continuation_cursor: Option<Vec<u8>>) -> Self {
72        Self {
73            rows,
74            continuation_cursor,
75        }
76    }
77
78    /// Borrow grouped rows.
79    #[must_use]
80    pub const fn rows(&self) -> &[GroupedRow] {
81        self.rows.as_slice()
82    }
83
84    /// Borrow optional continuation cursor bytes.
85    #[must_use]
86    pub fn continuation_cursor(&self) -> Option<&[u8]> {
87        self.continuation_cursor.as_deref()
88    }
89
90    /// Consume into grouped rows and continuation cursor bytes.
91    #[must_use]
92    pub fn into_parts(self) -> (Vec<GroupedRow>, Option<Vec<u8>>) {
93        (self.rows, self.continuation_cursor)
94    }
95}
96
97///
98/// PagedGroupedExecutionWithTrace
99///
100/// Cursor-paged grouped execution payload plus optional route/execution trace.
101///
102
103#[derive(Clone, Debug)]
104pub struct PagedGroupedExecutionWithTrace {
105    rows: Vec<GroupedRow>,
106    continuation_cursor: Option<Vec<u8>>,
107    execution_trace: Option<ExecutionTrace>,
108}
109
110impl PagedGroupedExecutionWithTrace {
111    /// Construct one traced grouped paged execution payload.
112    #[must_use]
113    pub const fn new(
114        rows: Vec<GroupedRow>,
115        continuation_cursor: Option<Vec<u8>>,
116        execution_trace: Option<ExecutionTrace>,
117    ) -> Self {
118        Self {
119            rows,
120            continuation_cursor,
121            execution_trace,
122        }
123    }
124
125    /// Borrow grouped rows.
126    #[must_use]
127    pub const fn rows(&self) -> &[GroupedRow] {
128        self.rows.as_slice()
129    }
130
131    /// Borrow optional continuation cursor bytes.
132    #[must_use]
133    pub fn continuation_cursor(&self) -> Option<&[u8]> {
134        self.continuation_cursor.as_deref()
135    }
136
137    /// Borrow optional execution trace details.
138    #[must_use]
139    pub const fn execution_trace(&self) -> Option<&ExecutionTrace> {
140        self.execution_trace.as_ref()
141    }
142
143    /// Consume payload and drop trace details.
144    #[must_use]
145    pub fn into_execution(self) -> PagedGroupedExecution {
146        PagedGroupedExecution {
147            rows: self.rows,
148            continuation_cursor: self.continuation_cursor,
149        }
150    }
151
152    /// Consume into grouped rows, continuation cursor bytes, and optional trace.
153    #[must_use]
154    pub fn into_parts(self) -> (Vec<GroupedRow>, Option<Vec<u8>>, Option<ExecutionTrace>) {
155        (self.rows, self.continuation_cursor, self.execution_trace)
156    }
157}