use std::collections::HashSet;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use super::{KeyValueOpts, NumberSeriesStyleDefaultConfig};
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct ColumnConfigSchema {
pub fields: Vec<ControlSpec>,
}
impl ColumnConfigSchema {
pub fn active_keys(&self) -> HashSet<String> {
let mut out = HashSet::new();
for spec in &self.fields {
for k in spec.serialized_keys() {
out.insert(k.to_string());
}
}
out
}
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(tag = "kind")]
pub enum ControlSpec {
Enum {
key: String,
variants: Vec<EnumVariant>,
default: String,
},
Bool {
key: String,
default: bool,
},
Number {
key: String,
default: f64,
#[serde(default, skip_serializing_if = "Option::is_none")]
include: Option<bool>,
#[serde(default, skip_serializing_if = "Option::is_none")]
min: Option<f64>,
#[serde(default, skip_serializing_if = "Option::is_none")]
max: Option<f64>,
#[serde(default, skip_serializing_if = "Option::is_none")]
step: Option<f64>,
},
String {
key: String,
default: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
placeholder: Option<String>,
},
Color {
key: String,
default: String,
},
ColorRange {
key_pos: String,
key_neg: String,
default_pos: String,
default_neg: String,
#[serde(default)]
is_gradient: bool,
},
DatetimeFormat,
StringFormat,
NumberSeriesStyle {
default: NumberSeriesStyleDefaultConfig,
},
Symbols {
default: KeyValueOpts,
},
NumberFormat,
AggregateDepth,
}
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
pub struct EnumVariant {
pub value: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub label: Option<String>,
}
impl ControlSpec {
pub fn serialized_keys(&self) -> Vec<&str> {
match self {
ControlSpec::DatetimeFormat => vec!["date_format"],
ControlSpec::StringFormat => vec!["format"],
ControlSpec::NumberSeriesStyle { .. } => vec!["chart_type", "stack"],
ControlSpec::Symbols { .. } => vec!["symbols"],
ControlSpec::NumberFormat => vec!["number_format"],
ControlSpec::AggregateDepth => vec!["aggregate_depth"],
ControlSpec::ColorRange {
key_pos, key_neg, ..
} => vec![key_pos.as_str(), key_neg.as_str()],
ControlSpec::Enum { key, .. }
| ControlSpec::Bool { key, .. }
| ControlSpec::Number { key, .. }
| ControlSpec::String { key, .. }
| ControlSpec::Color { key, .. } => vec![key.as_str()],
}
}
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct ColumnConfigFieldUpdate {
pub keys: Vec<String>,
pub value: serde_json::Map<String, Value>,
}
pub fn filter_to_schema(
config: &serde_json::Map<String, Value>,
active_keys: &HashSet<String>,
) -> serde_json::Map<String, Value> {
config
.iter()
.filter(|(k, _)| active_keys.contains(k.as_str()))
.map(|(k, v)| (k.clone(), v.clone()))
.collect()
}