use crate::value::OutputValue;
use candid::CandidType;
use serde::Deserialize;
#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq)]
pub struct GroupedRow {
group_key: Vec<OutputValue>,
aggregate_values: Vec<OutputValue>,
}
impl GroupedRow {
#[must_use]
pub fn new<I, J, K, L>(group_key: I, aggregate_values: J) -> Self
where
I: IntoIterator<Item = K>,
J: IntoIterator<Item = L>,
K: Into<OutputValue>,
L: Into<OutputValue>,
{
Self {
group_key: group_key.into_iter().map(Into::into).collect(),
aggregate_values: aggregate_values.into_iter().map(Into::into).collect(),
}
}
#[must_use]
pub const fn group_key(&self) -> &[OutputValue] {
self.group_key.as_slice()
}
#[must_use]
pub const fn aggregate_values(&self) -> &[OutputValue] {
self.aggregate_values.as_slice()
}
}
#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq)]
pub struct GroupedQueryOutput {
pub entity: String,
pub rows: Vec<GroupedRow>,
pub row_count: u32,
pub next_cursor: Option<String>,
}
#[cfg(test)]
mod tests {
use candid::CandidType;
use super::{GroupedQueryOutput, GroupedRow};
use crate::value::OutputValue;
#[derive(CandidType)]
struct FrozenGroupedRowWire {
group_key: Vec<OutputValue>,
aggregate_values: Vec<OutputValue>,
}
#[derive(CandidType)]
struct FrozenGroupedQueryOutputWire {
entity: String,
rows: Vec<FrozenGroupedRowWire>,
row_count: u32,
next_cursor: Option<String>,
}
#[test]
fn grouped_query_output_preserves_its_initial_candid_record_shape() {
let current = GroupedQueryOutput {
entity: "Example".to_string(),
rows: vec![GroupedRow::new(
[OutputValue::Nat64(7)],
[OutputValue::Nat64(1)],
)],
row_count: 1,
next_cursor: Some("abcd".to_string()),
};
let frozen = FrozenGroupedQueryOutputWire {
entity: current.entity.clone(),
rows: vec![FrozenGroupedRowWire {
group_key: vec![OutputValue::Nat64(7)],
aggregate_values: vec![OutputValue::Nat64(1)],
}],
row_count: current.row_count,
next_cursor: current.next_cursor.clone(),
};
assert_eq!(
candid::encode_one(¤t).expect("current grouped output should encode"),
candid::encode_one(&frozen).expect("frozen grouped output should encode"),
);
}
}