use super::Component;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Crosstab {
#[serde(default)]
pub title: Option<String>,
pub row_dimension: String,
pub column_dimension: String,
pub measure: String,
#[serde(default = "default_aggregation")]
pub aggregation: String,
pub data: Vec<HashMap<String, serde_json::Value>>,
#[serde(default = "default_true")]
pub show_row_totals: bool,
#[serde(default = "default_true")]
pub show_column_totals: bool,
#[serde(default = "default_true")]
pub show_grand_total: bool,
}
fn default_aggregation() -> String {
"sum".into()
}
fn default_true() -> bool {
true
}
impl Crosstab {
pub fn new(
row_dimension: impl Into<String>,
column_dimension: impl Into<String>,
measure: impl Into<String>,
) -> Self {
Self {
title: None,
row_dimension: row_dimension.into(),
column_dimension: column_dimension.into(),
measure: measure.into(),
aggregation: "sum".into(),
data: Vec::new(),
show_row_totals: true,
show_column_totals: true,
show_grand_total: true,
}
}
pub fn with_title(mut self, title: impl Into<String>) -> Self {
self.title = Some(title.into());
self
}
pub fn with_data(mut self, data: Vec<HashMap<String, serde_json::Value>>) -> Self {
self.data = data;
self
}
pub fn with_aggregation(mut self, aggregation: impl Into<String>) -> Self {
self.aggregation = aggregation.into();
self
}
pub fn hide_totals(mut self) -> Self {
self.show_row_totals = false;
self.show_column_totals = false;
self.show_grand_total = false;
self
}
}
impl Component for Crosstab {
fn component_id(&self) -> &'static str {
"crosstab"
}
fn to_data(&self) -> serde_json::Value {
serde_json::to_value(self).unwrap_or_default()
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PivotTable {
#[serde(default)]
pub title: Option<String>,
pub row_headers: Vec<String>,
pub column_headers: Vec<String>,
pub values: Vec<Vec<String>>,
#[serde(default = "default_true")]
pub show_borders: bool,
}
impl PivotTable {
pub fn new(
row_headers: Vec<String>,
column_headers: Vec<String>,
values: Vec<Vec<String>>,
) -> Self {
Self {
title: None,
row_headers,
column_headers,
values,
show_borders: true,
}
}
pub fn with_title(mut self, title: impl Into<String>) -> Self {
self.title = Some(title.into());
self
}
}
impl Component for PivotTable {
fn component_id(&self) -> &'static str {
"pivot-table"
}
fn to_data(&self) -> serde_json::Value {
serde_json::to_value(self).unwrap_or_default()
}
}