#[derive(serde::Serialize, serde::Deserialize, PartialEq, Clone, Debug)]
pub struct Widget {
pub id: String,
pub label: String,
pub widget: String,
pub input_type: String,
pub name: String,
pub value: String,
pub placeholder: String,
pub pattern: String,
pub minlength: usize,
pub maxlength: usize,
pub required: bool,
pub checked: bool,
pub unique: bool,
pub disabled: bool,
pub readonly: bool,
pub step: String,
pub min: String,
pub max: String,
pub other_attrs: String,
pub css_classes: String,
pub options: Vec<(String, String)>,
pub hint: String,
pub warning: String,
pub error: String,
}
impl Default for Widget {
fn default() -> Self {
Widget {
id: String::new(),
label: String::new(),
widget: String::from("inputText"),
input_type: String::from("text"),
name: String::new(),
value: String::new(),
placeholder: String::new(),
pattern: String::new(),
minlength: 0_usize,
maxlength: 256_usize,
required: false,
checked: false,
unique: false,
disabled: false,
readonly: false,
step: String::from("0"),
min: String::from("0"),
max: String::from("0"),
other_attrs: String::new(),
css_classes: String::new(),
options: Vec::new(),
hint: String::new(),
warning: String::new(),
error: String::new(),
}
}
}
#[derive(serde::Deserialize)]
pub struct TransMapWidgets {
pub map_widgets: std::collections::HashMap<String, Widget>,
}
pub trait ToForm {
fn key_store() -> Result<String, Box<dyn std::error::Error>>;
fn widgets() -> Result<std::collections::HashMap<String, Widget>, Box<dyn std::error::Error>>;
}
pub trait HtmlControls {
fn to_html(
fields_name: &Vec<String>,
map_widgets: std::collections::HashMap<String, Widget>,
) -> Result<String, Box<dyn std::error::Error>> {
let mut controls = String::new();
for field_name in fields_name {
let attrs = map_widgets.get(field_name).unwrap();
match attrs.input_type.as_str() {
"text" | "url" | "tel" | "password" | "email" | "color" => {
controls = format!(
"{}<p>{}<input{}{}{}{}{}{}{}{}{}{}{}{}{}>{}{}{}</p>",
controls,
if !attrs.label.is_empty() {
format!("<label for=\"{}\">{}:</label><br>", attrs.id, attrs.label)
} else {
String::new()
},
format!(" id=\"{}\"", attrs.id),
format!(" type=\"{}\"", attrs.input_type),
format!(" name=\"{}\"", attrs.name),
format!(" value=\"{}\"", attrs.value),
if attrs.required { " required" } else { "" },
if attrs.disabled { " disabled" } else { "" },
if attrs.readonly { " readonly" } else { "" },
if !attrs.placeholder.is_empty() {
format!(" placeholder=\"{}\"", attrs.placeholder)
} else {
String::new()
},
if !attrs.pattern.is_empty() {
format!(" pattern=\"{}\"", attrs.pattern)
} else {
String::new()
},
if !attrs.minlength > 0 {
format!(" minlength=\"{}\"", attrs.minlength)
} else {
String::new()
},
if !attrs.maxlength > 0 {
format!(" maxlength=\"{}\"", attrs.maxlength)
} else {
String::new()
},
if !attrs.css_classes.is_empty() {
format!(" class=\"{}\"", attrs.css_classes)
} else {
String::new()
},
if !attrs.other_attrs.is_empty() {
format!(" {}", attrs.other_attrs)
} else {
String::new()
},
if !attrs.hint.is_empty() {
format!("<br><small class=\"hint\">{}</small>", attrs.hint)
} else {
String::new()
},
if !attrs.warning.is_empty() {
format!("<br><small class=\"warning\">{}</small>", attrs.warning)
} else {
String::new()
},
if !attrs.error.is_empty() {
format!("<br><small class=\"error\">{}</small>", attrs.error)
} else {
String::new()
}
);
}
"checkbox" => {
controls = format!(
"{}<p><input{}{}{}{}{}{}{}{}{}>{}{}{}{}</p>",
controls,
format!(" id=\"{}\"", attrs.id),
format!(" type=\"{}\"", attrs.input_type),
format!(" name=\"{}\"", attrs.name),
format!(
" value=\"{}\"",
if attrs.widget == "checkBoxBool".to_string() {
true.to_string()
} else {
attrs.value.clone()
}
),
if attrs.checked { " checked" } else { "" },
if attrs.disabled { " disabled" } else { "" },
if attrs.readonly { " readonly" } else { "" },
if !attrs.css_classes.is_empty() {
format!(" class=\"{}\"", attrs.css_classes)
} else {
String::new()
},
if !attrs.other_attrs.is_empty() {
format!(" {}", attrs.other_attrs)
} else {
String::new()
},
if !attrs.label.is_empty() {
format!("<label for=\"{}\">{}:</label>", attrs.id, attrs.label)
} else {
format!("<label for=\"{}\">{}:</label>", attrs.id, "Untitled")
},
if !attrs.hint.is_empty() {
format!("<br><small class=\"hint\">{}</small>", attrs.hint)
} else {
String::new()
},
if !attrs.warning.is_empty() {
format!("<br><small class=\"warning\">{}</small>", attrs.warning)
} else {
String::new()
},
if !attrs.error.is_empty() {
format!("<br><small class=\"error\">{}</small>", attrs.error)
} else {
String::new()
}
);
}
"radio" => {
let mut inputs = String::new();
for item in attrs.options.iter() {
inputs = format!(
"{}<p><input{}{}{}{}{}{}{}{}{}>{}{}{}{}</p>",
inputs,
format!(" id=\"{}\"", attrs.id),
format!(" type=\"{}\"", attrs.input_type),
format!(" name=\"{}\"", attrs.name),
format!(" value=\"{}\"", item.0),
if attrs.checked { " checked " } else { "" },
if attrs.disabled { " disabled" } else { "" },
if attrs.readonly { " readonly" } else { "" },
if !attrs.css_classes.is_empty() {
format!(" class=\"{}\"", attrs.css_classes)
} else {
String::new()
},
if !attrs.other_attrs.is_empty() {
format!(" {}", attrs.other_attrs)
} else {
String::new()
},
if !attrs.label.is_empty() {
format!("<label for=\"{}\">{}:</label>", attrs.id, attrs.label)
} else {
format!("<label for=\"{}\">{}:</label>", attrs.id, "Untitled")
},
if !attrs.hint.is_empty() {
format!("<br><small class=\"hint\">{}</small>", attrs.hint)
} else {
String::new()
},
if !attrs.warning.is_empty() {
format!("<br><small class=\"warning\">{}</small>", attrs.warning)
} else {
String::new()
},
if !attrs.error.is_empty() {
format!("<br><small class=\"error\">{}</small>", attrs.error)
} else {
String::new()
}
);
}
controls = format!("{}{}", controls, inputs);
}
"date" | "datetime" => {
controls = format!(
"{}<p>{}<input{}{}{}{}{}{}{}{}{}{}{}>{}{}{}</p>",
controls,
if !attrs.label.is_empty() {
format!("<label for=\"{}\">{}:</label><br>", attrs.id, attrs.label)
} else {
String::new()
},
format!(" id=\"{}\"", attrs.id),
format!(" type=\"{}\"", attrs.input_type),
format!(" name=\"{}\"", attrs.name),
format!(" value=\"{}\"", attrs.value),
if attrs.required { " required" } else { "" },
if attrs.disabled { " disabled" } else { "" },
if attrs.readonly { " readonly" } else { "" },
if !attrs.placeholder.is_empty() {
format!(" placeholder=\"{}\"", attrs.placeholder)
} else {
String::new()
},
if !attrs.pattern.is_empty() {
format!(" pattern=\"{}\"", attrs.pattern)
} else {
String::new()
},
if !attrs.css_classes.is_empty() {
format!(" class=\"{}\" ", attrs.css_classes)
} else {
String::new()
},
if !attrs.other_attrs.is_empty() {
format!(" {}", attrs.other_attrs)
} else {
String::new()
},
if !attrs.hint.is_empty() {
format!("<br><small class=\"hint\">{}</small>", attrs.hint)
} else {
String::new()
},
if !attrs.warning.is_empty() {
format!("<br><small class=\"warning\">{}</small>", attrs.warning)
} else {
String::new()
},
if !attrs.error.is_empty() {
format!("<br><small class=\"error\">{}</small>", attrs.error)
} else {
String::new()
}
);
}
"file" => {
controls = format!(
"{}<p>{}<input{}{}{}{}{}{}{}{}>{}{}{}</p>",
controls,
if !attrs.label.is_empty() {
format!("<label for=\"{}\">{}:</label><br>", attrs.id, attrs.label)
} else {
String::new()
},
format!(" id=\"{}\"", attrs.id),
format!(" type=\"{}\"", attrs.input_type),
format!(" name=\"{}\"", attrs.name),
if attrs.required { " required" } else { "" },
if attrs.disabled { " disabled" } else { "" },
if attrs.readonly { " readonly" } else { "" },
if !attrs.css_classes.is_empty() {
format!(" class=\"{}\"", attrs.css_classes)
} else {
String::new()
},
if !attrs.other_attrs.is_empty() {
format!(" {}", attrs.other_attrs)
} else {
String::new()
},
if !attrs.hint.is_empty() {
format!("<br><small class=\"hint\">{}</small>", attrs.hint)
} else {
String::new()
},
if !attrs.warning.is_empty() {
format!("<br><small class=\"warning\">{}</small>", attrs.warning)
} else {
String::new()
},
if !attrs.error.is_empty() {
format!("<br><small class=\"error\">{}</small>", attrs.error)
} else {
String::new()
}
);
}
"number" => {
controls = format!(
"{}<p>{}<input{}{}{}{}{}{}{}{}{}{}{}{}{}>{}{}{}</p>",
controls,
if !attrs.label.is_empty() {
format!("<label for=\"{}\">{}:</label><br>", attrs.id, attrs.label)
} else {
String::new()
},
format!(" id=\"{}\"", attrs.id),
format!(" type=\"{}\"", attrs.input_type),
format!(" name=\"{}\"", attrs.name),
format!(" value=\"{}\"", attrs.value),
if attrs.required { " required" } else { "" },
if attrs.disabled { " disabled" } else { "" },
if attrs.readonly { " readonly" } else { "" },
if !attrs.placeholder.is_empty() {
format!(" placeholder=\"{}\"", attrs.placeholder)
} else {
String::new()
},
if attrs.step != "0" {
format!(" step=\"{}\"", attrs.step)
} else {
String::new()
},
if attrs.min != "0" {
format!(" min=\"{}\"", attrs.step)
} else {
String::new()
},
if attrs.max != "0" {
format!(" max=\"{}\"", attrs.step)
} else {
String::new()
},
if !attrs.css_classes.is_empty() {
format!(" class=\"{}\"", attrs.css_classes)
} else {
String::new()
},
if !attrs.other_attrs.is_empty() {
format!(" {}", attrs.other_attrs)
} else {
String::new()
},
if !attrs.hint.is_empty() {
format!("<br><small class=\"hint\">{}</small>", attrs.hint)
} else {
String::new()
},
if !attrs.warning.is_empty() {
format!("<br><small class=\"warning\">{}</small>", attrs.warning)
} else {
String::new()
},
if !attrs.error.is_empty() {
format!("<br><small class=\"error\">{}</small>", attrs.error)
} else {
String::new()
}
);
}
"range" => {
controls = format!(
"{}<p>{}<input{}{}{}{}{}{}{}{}{}{}{}{}>{}{}{}</p>",
controls,
if !attrs.label.is_empty() {
format!("<label for=\"{}\">{}:</label><br>", attrs.id, attrs.label)
} else {
String::new()
},
format!(" id=\"{}\"", attrs.id),
format!(" type=\"{}\"", attrs.input_type),
format!(" name=\"{}\"", attrs.name),
format!(" value=\"{}\"", attrs.value),
if attrs.required { " required" } else { "" },
if attrs.disabled { " disabled" } else { "" },
if attrs.readonly { " readonly" } else { "" },
if attrs.step != "0" {
format!(" step=\"{}\"", attrs.step)
} else {
String::new()
},
if attrs.min != "0" {
format!(" min=\"{}\"", attrs.step)
} else {
String::new()
},
if attrs.max != "0" {
format!(" max=\"{}\"", attrs.step)
} else {
String::new()
},
if !attrs.css_classes.is_empty() {
format!(" class=\"{}\"", attrs.css_classes)
} else {
String::new()
},
if !attrs.other_attrs.is_empty() {
format!(" {}", attrs.other_attrs)
} else {
String::new()
},
if !attrs.hint.is_empty() {
format!("<br><small class=\"hint\">{}</small>", attrs.hint)
} else {
String::new()
},
if !attrs.warning.is_empty() {
format!("<br><small class=\"warning\">{}</small>", attrs.warning)
} else {
String::new()
},
if !attrs.error.is_empty() {
format!("<br><small class=\"error\">{}</small>", attrs.error)
} else {
String::new()
}
);
}
"textarea" => {
controls = format!(
"{}<p>{}<textarea{}{}{}{}{}{}{}{}{}{}>{}</textarea>{}{}{}</p>",
controls,
if !attrs.label.is_empty() {
format!("<label for=\"{}\">{}:</label><br>", attrs.id, attrs.label)
} else {
String::new()
},
format!(" id=\"{}\"", attrs.id),
format!(" name=\"{}\"", attrs.name),
if attrs.required { " required" } else { "" },
if attrs.disabled { " disabled" } else { "" },
if attrs.readonly { " readonly" } else { "" },
if !attrs.minlength > 0 {
format!(" minlength=\"{}\"", attrs.minlength)
} else {
String::new()
},
if !attrs.maxlength > 0 {
format!(" maxlengt\"{}\"", attrs.maxlength)
} else {
String::new()
},
if !attrs.placeholder.is_empty() {
format!(" placeholder=\"{}\"", attrs.placeholder)
} else {
String::new()
},
if !attrs.css_classes.is_empty() {
format!(" class=\"{}\"", attrs.css_classes)
} else {
String::new()
},
if !attrs.other_attrs.is_empty() {
format!(" {}", attrs.other_attrs)
} else {
String::new()
},
attrs.value,
if !attrs.hint.is_empty() {
format!("<br><small class=\"hint\">{}</small>", attrs.hint)
} else {
String::new()
},
if !attrs.warning.is_empty() {
format!("<br><small class=\"warning\">{}</small>", attrs.warning)
} else {
String::new()
},
if !attrs.error.is_empty() {
format!("<br><small class=\"error\">{}</small>", attrs.error)
} else {
String::new()
}
);
}
"select" => {
let mut options = String::new();
for item in attrs.options.iter() {
options = format!(
"{}<option{}value=\"{}\">{}</option>",
options,
if attrs.value == item.0 {
" selected "
} else {
" "
},
item.0,
item.1
);
}
controls = format!(
"{}<p>{}<select{}{}{}{}{}{}{}>{}</select>{}{}{}</p>",
controls,
if !attrs.label.is_empty() {
format!("<label for=\"{}\">{}:</label><br>", attrs.id, attrs.label)
} else {
String::new()
},
format!(" id=\"{}\"", attrs.id),
format!(" name=\"{}\"", attrs.name),
if attrs.required { " required" } else { "" },
if attrs.disabled { " disabled" } else { "" },
if attrs.readonly { " readonly" } else { "" },
if !attrs.css_classes.is_empty() {
format!(" class=\"{}\"", attrs.css_classes)
} else {
String::new()
},
if !attrs.other_attrs.is_empty() {
format!(" {}", attrs.other_attrs)
} else {
String::new()
},
options,
if !attrs.hint.is_empty() {
format!("<br><small class=\"hint\">{}</small>", attrs.hint)
} else {
String::new()
},
if !attrs.warning.is_empty() {
format!("<br><small class=\"warning\">{}</small>", attrs.warning)
} else {
String::new()
},
if !attrs.error.is_empty() {
format!("<br><small class=\"error\">{}</small>", attrs.error)
} else {
String::new()
}
);
}
"hidden" => {
controls = format!(
"{}<input{}{}{}{}{}{}{}>",
controls,
format!(" id=\"{}\"", attrs.id),
format!(" type=\"{}\"", attrs.input_type),
format!(" name=\"{}\"", attrs.name),
format!(" value=\"{}\"", attrs.value),
if attrs.required { " required" } else { "" },
if !attrs.css_classes.is_empty() {
format!(" class=\"{}\"", attrs.css_classes)
} else {
String::new()
},
if !attrs.other_attrs.is_empty() {
format!(" {}", attrs.other_attrs)
} else {
String::new()
}
);
}
_ => panic!("Invalid input type."),
}
}
controls = format!("{}<p><input type=\"submit\" value=\"Save\"></p>", controls);
Ok(controls)
}
}
pub enum OutputType {
Hash,
Wig,
Json,
Html,
}
#[derive(Debug)]
pub enum OutputData {
Hash((String, bool, mongodb::bson::document::Document)),
Wig(
(
std::collections::HashMap<String, Widget>,
bool,
mongodb::bson::document::Document,
),
),
Json((String, bool, mongodb::bson::document::Document)),
Html((String, bool, mongodb::bson::document::Document)),
}
impl OutputData {
pub fn hash(&self) -> &str {
match self {
Self::Hash(data) => &data.0,
_ => panic!("`hash()` : Doesn't match the output type."),
}
}
pub fn wig(&self) -> std::collections::HashMap<String, Widget> {
match self {
Self::Wig(data) => data.0.clone(),
_ => panic!("`wig()` : Doesn't match the output type."),
}
}
pub fn json(&self) -> &str {
match self {
Self::Json(data) => &data.0,
_ => panic!("`json()` : Doesn't match the output type."),
}
}
pub fn html(&self) -> &str {
match self {
Self::Html(data) => &data.0,
_ => panic!("`html()` : Doesn't match the output type."),
}
}
pub fn bool(&self) -> bool {
match self {
Self::Hash(data) => data.1,
Self::Wig(data) => data.1,
Self::Json(data) => data.1,
Self::Html(data) => data.1,
}
}
pub fn doc(&self) -> mongodb::bson::document::Document {
match self {
Self::Hash(data) => data.2.clone(),
Self::Wig(data) => data.2.clone(),
Self::Json(data) => data.2.clone(),
Self::Html(data) => data.2.clone(),
}
}
}