use candid::CandidType;
use icydb_core::value::OutputValue;
use serde::Deserialize;
pub use icydb_core::value::render_output_value_text;
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct ProjectionRows {
columns: Vec<String>,
rows: Vec<Vec<OutputValue>>,
row_count: u32,
}
impl ProjectionRows {
#[must_use]
pub const fn new(columns: Vec<String>, rows: Vec<Vec<OutputValue>>, row_count: u32) -> Self {
Self {
columns,
rows,
row_count,
}
}
#[must_use]
pub const fn columns(&self) -> &[String] {
self.columns.as_slice()
}
#[must_use]
pub const fn rows(&self) -> &[Vec<OutputValue>] {
self.rows.as_slice()
}
#[must_use]
pub fn rendered_rows(&self) -> Vec<Vec<String>> {
render_rows(self.rows.as_slice())
}
#[must_use]
pub const fn row_count(&self) -> u32 {
self.row_count
}
#[must_use]
pub fn into_columns_rows_and_count(self) -> (Vec<String>, Vec<Vec<OutputValue>>, u32) {
(self.columns, self.rows, self.row_count)
}
}
#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq)]
pub struct RowProjectionOutput {
pub entity: String,
pub columns: Vec<String>,
pub rows: Vec<Vec<OutputValue>>,
pub row_count: u32,
}
impl RowProjectionOutput {
#[must_use]
pub fn from_projection(entity: String, projection: ProjectionRows) -> Self {
let (columns, rows, row_count) = projection.into_columns_rows_and_count();
Self {
entity,
columns,
rows,
row_count,
}
}
#[must_use]
pub fn as_projection_rows(&self) -> ProjectionRows {
ProjectionRows::new(self.columns.clone(), self.rows.clone(), self.row_count)
}
#[must_use]
pub fn rendered_rows(&self) -> Vec<Vec<String>> {
render_rows(self.rows.as_slice())
}
}
fn render_rows(rows: &[Vec<OutputValue>]) -> Vec<Vec<String>> {
rows.iter()
.map(|row| row.iter().map(render_output_value_text).collect())
.collect()
}