You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
157 lines
5.1 KiB
157 lines
5.1 KiB
use crate::store::model::FieldKind;
|
|
use serde_json::Value;
|
|
use std::borrow::Cow;
|
|
use crate::store::{model, Indexes};
|
|
|
|
use lazy_static::lazy_static;
|
|
|
|
lazy_static! {
|
|
/// This is an example for using doc comment attributes
|
|
static ref EMPTY_VEC: Vec<String> = vec![];
|
|
}
|
|
|
|
#[derive(Serialize, Debug, Default)]
|
|
pub struct RenderedField<'a> {
|
|
pub key: Cow<'a, str>,
|
|
pub label: Cow<'a, str>,
|
|
pub kind: &'static str,
|
|
pub step: &'static str,
|
|
pub min: String,
|
|
pub max: String,
|
|
pub all_tags_json: String,
|
|
pub tags_json: String,
|
|
pub options: Option<&'a Vec<String>>,
|
|
pub value: Cow<'a, str>,
|
|
pub checked: bool,
|
|
}
|
|
|
|
impl<'a> RenderedField<'a> {
|
|
pub fn from_template_field<'i>(
|
|
key: &'i String,
|
|
field: &'i model::Field,
|
|
value: Option<&'i Value>,
|
|
index: &'i Indexes
|
|
) -> RenderedField<'i> {
|
|
let mut rendered = RenderedField::default();
|
|
rendered.key = key.as_str().into();
|
|
rendered.label = if field.label.is_empty() {
|
|
titlecase::titlecase(&key.replace('_', " ")).into()
|
|
} else {
|
|
field.label.as_str().into()
|
|
};
|
|
|
|
match &field.kind {
|
|
FieldKind::String => {
|
|
rendered.kind = "string";
|
|
}
|
|
FieldKind::Text => {
|
|
rendered.kind = "text";
|
|
}
|
|
FieldKind::Bool { default } => {
|
|
rendered.kind = "bool";
|
|
|
|
rendered.checked = if let Some(Value::Bool(v)) = value {
|
|
*v
|
|
} else {
|
|
*default
|
|
}
|
|
}
|
|
FieldKind::Int { min, max, default } => {
|
|
rendered.kind = "number";
|
|
|
|
let num = if let Some(Value::Number(n)) = value {
|
|
n.as_i64().expect("Error parsing number")
|
|
} else {
|
|
*default
|
|
};
|
|
|
|
if let Some(n) = min {
|
|
rendered.min = n.to_string();
|
|
}
|
|
|
|
if let Some(n) = max {
|
|
rendered.max = n.to_string();
|
|
}
|
|
|
|
rendered.value = Cow::Owned(num.to_string());
|
|
rendered.step = "1";
|
|
}
|
|
FieldKind::Float { min, max, default } => {
|
|
rendered.kind = "number";
|
|
|
|
let num = if let Some(Value::Number(n)) = value {
|
|
n.as_f64().expect("Error parsing number")
|
|
} else {
|
|
*default
|
|
};
|
|
|
|
if let Some(n) = min {
|
|
rendered.min = n.to_string();
|
|
}
|
|
|
|
if let Some(n) = max {
|
|
rendered.max = n.to_string();
|
|
}
|
|
|
|
rendered.value = Cow::Owned(num.to_string());
|
|
rendered.step = "any";
|
|
}
|
|
FieldKind::Enum { options, default } => {
|
|
rendered.kind = "select";
|
|
rendered.options = Some(options);
|
|
|
|
if let Some(Value::String(s)) = value {
|
|
rendered.value = Cow::Borrowed(&s.as_str());
|
|
} else if let Some(def) = default {
|
|
rendered.value = def.to_owned().into();
|
|
}
|
|
}
|
|
FieldKind::FreeEnum { enum_group } => {
|
|
rendered.kind = "free_select";
|
|
let group = enum_group.as_ref().unwrap_or(key);
|
|
let options = index.free_enums.get(group).unwrap_or(&EMPTY_VEC);
|
|
rendered.options = Some(options);
|
|
}
|
|
FieldKind::Tags { options } => {
|
|
rendered.kind = "tags";
|
|
rendered.options = Some(options);
|
|
|
|
rendered.all_tags_json = serde_json::to_string(options).unwrap();
|
|
}
|
|
FieldKind::FreeTags { tag_group } => {
|
|
rendered.kind = "free_tags";
|
|
let group = tag_group.as_ref().unwrap_or(key);
|
|
let options = index.free_tags.get(group).unwrap_or(&EMPTY_VEC);
|
|
|
|
rendered.options = Some(options);
|
|
rendered.all_tags_json = "[]".into();
|
|
}
|
|
}
|
|
|
|
// Shared code by multiple variants
|
|
match field.kind {
|
|
FieldKind::Text | FieldKind::String => {
|
|
if let Some(Value::String(s)) = value {
|
|
rendered.value = Cow::Borrowed(&s.as_str());
|
|
}
|
|
},
|
|
FieldKind::Enum { .. } | FieldKind::FreeEnum { .. } => {
|
|
if let Some(Value::String(s)) = value {
|
|
rendered.value = Cow::Borrowed(&s.as_str());
|
|
}
|
|
},
|
|
FieldKind::Tags { .. } | FieldKind::FreeTags { .. } => {
|
|
if let Some(v) = value {
|
|
rendered.value = serde_json::from_value::<Vec<String>>(v.clone())
|
|
.unwrap().join(" ").into();
|
|
rendered.tags_json = serde_json::to_string(v).unwrap();
|
|
} else {
|
|
rendered.tags_json = "[]".into();
|
|
}
|
|
},
|
|
_ => {}
|
|
}
|
|
|
|
rendered
|
|
}
|
|
}
|
|
|