icydb_core/db/response/
grouped.rs1use crate::value::OutputValue;
7
8use serde::Deserialize;
9
10#[derive(Clone, Debug, Deserialize, Eq, PartialEq, serde::Serialize)]
19pub struct GroupedRow {
20 group_key: Vec<OutputValue>,
21 aggregate_values: Vec<OutputValue>,
22}
23
24impl GroupedRow {
25 #[must_use]
27 pub fn new<I, J, K, L>(group_key: I, aggregate_values: J) -> Self
28 where
29 I: IntoIterator<Item = K>,
30 J: IntoIterator<Item = L>,
31 K: Into<OutputValue>,
32 L: Into<OutputValue>,
33 {
34 Self {
35 group_key: group_key.into_iter().map(Into::into).collect(),
36 aggregate_values: aggregate_values.into_iter().map(Into::into).collect(),
37 }
38 }
39
40 #[must_use]
42 pub const fn group_key(&self) -> &[OutputValue] {
43 self.group_key.as_slice()
44 }
45
46 #[must_use]
48 pub const fn aggregate_values(&self) -> &[OutputValue] {
49 self.aggregate_values.as_slice()
50 }
51}
52
53#[derive(Clone, Debug, Deserialize, Eq, PartialEq, serde::Serialize)]
55pub struct GroupedQueryOutput {
56 pub entity: String,
58 pub rows: Vec<GroupedRow>,
60 pub row_count: u32,
62 pub next_cursor: Option<String>,
64}
65
66#[cfg(test)]
67mod tests {
68
69 use super::{GroupedQueryOutput, GroupedRow};
70 use crate::value::OutputValue;
71
72 #[derive(serde::Serialize)]
73 struct FrozenGroupedRowWire {
74 group_key: Vec<OutputValue>,
75 aggregate_values: Vec<OutputValue>,
76 }
77
78 #[derive(serde::Serialize)]
79 struct FrozenGroupedQueryOutputWire {
80 entity: String,
81 rows: Vec<FrozenGroupedRowWire>,
82 row_count: u32,
83 next_cursor: Option<String>,
84 }
85
86 #[test]
87 fn grouped_query_output_preserves_its_initial_wire_record_shape() {
88 let current = GroupedQueryOutput {
89 entity: "Example".to_string(),
90 rows: vec![GroupedRow::new(
91 [OutputValue::nat64(7)],
92 [OutputValue::nat64(1)],
93 )],
94 row_count: 1,
95 next_cursor: Some("abcd".to_string()),
96 };
97 let frozen = FrozenGroupedQueryOutputWire {
98 entity: current.entity.clone(),
99 rows: vec![FrozenGroupedRowWire {
100 group_key: vec![OutputValue::nat64(7)],
101 aggregate_values: vec![OutputValue::nat64(1)],
102 }],
103 row_count: current.row_count,
104 next_cursor: current.next_cursor.clone(),
105 };
106
107 assert_eq!(
108 icydb_schema::wire::encode_one(¤t).expect("current grouped output should encode"),
109 icydb_schema::wire::encode_one(&frozen).expect("frozen grouped output should encode"),
110 );
111 }
112}