Skip to main content

icydb_core/db/response/
rows.rs

1//! Module: response::rows
2//! Responsibility: engine-neutral projected-row response payloads.
3//! Does not own: query execution, SQL adaptation, or typed row decoding.
4//! Boundary: shared dynamic/SQL projection output over accepted public values.
5
6use crate::value::{OutputValue, render_output_value_text};
7use candid::CandidType;
8use serde::Deserialize;
9
10/// Row-oriented output from one accepted-schema-driven projection.
11#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq)]
12pub struct RowProjectionOutput {
13    /// Accepted entity name used for the read.
14    pub entity: String,
15    /// Selected output-column names in row order.
16    pub columns: Vec<String>,
17    /// Row-oriented output values.
18    pub rows: Vec<Vec<OutputValue>>,
19    /// Number of returned rows.
20    pub row_count: u32,
21}
22
23impl RowProjectionOutput {
24    /// Render row values into stable display strings.
25    #[must_use]
26    pub fn rendered_rows(&self) -> Vec<Vec<String>> {
27        self.rows
28            .iter()
29            .map(|row| row.iter().map(render_output_value_text).collect())
30            .collect()
31    }
32}
33
34#[cfg(test)]
35mod tests {
36    use super::*;
37
38    #[derive(CandidType)]
39    struct FrozenRowProjectionOutputWire {
40        entity: String,
41        columns: Vec<String>,
42        rows: Vec<Vec<OutputValue>>,
43        row_count: u32,
44    }
45
46    #[test]
47    fn row_projection_output_preserves_the_frozen_candid_record_shape() {
48        let current = RowProjectionOutput {
49            entity: "example".to_string(),
50            columns: vec!["id".to_string()],
51            rows: Vec::new(),
52            row_count: 0,
53        };
54        let frozen = FrozenRowProjectionOutputWire {
55            entity: current.entity.clone(),
56            columns: current.columns.clone(),
57            rows: current.rows.clone(),
58            row_count: current.row_count,
59        };
60
61        assert_eq!(
62            candid::encode_one(&current).expect("current row projection should encode"),
63            candid::encode_one(&frozen).expect("frozen row projection should encode"),
64        );
65    }
66}