use mongodb::bson::{doc, document::Document, oid::ObjectId};
use std::error::Error;
use crate::{
models::{
db_query_api::{commons::QCommons, paladins::QPaladins},
Meta,
},
widgets::Widget,
};
pub enum OutputDataAdmin<T> {
Instance(Option<T>),
EarlyResult(String),
}
pub trait Administrator: QCommons + QPaladins {
fn instance_to_json_for_admin(&self) -> Result<String, Box<dyn Error>> {
let (model_cache, _client_cache) = Self::get_cache_data_for_query()?;
let meta: Meta = model_cache.meta;
let map_widgets = model_cache.widget_map.clone();
let model_json = self.self_to_json()?;
let mut widget_list: Vec<Widget> = Vec::new();
let hash = self.get_hash();
for field_name in meta.fields_name.iter() {
let mut widget = map_widgets.get(field_name).unwrap().clone();
if !field_name.contains("password") {
let field_json = model_json[field_name].clone();
if field_json.is_string() {
widget.value = field_json.as_str().unwrap().to_string();
} else if field_json.is_i64() {
widget.value = field_json.as_i64().unwrap().to_string();
} else if field_json.is_u64() {
widget.value = field_json.as_u64().unwrap().to_string();
} else if field_json.is_f64() {
widget.value = field_json.as_f64().unwrap().to_string();
} else if field_json.is_array() {
let array = field_json.as_array().unwrap();
widget.value = serde_json::to_string(array)?;
} else if field_json.is_boolean() {
widget.checked = field_json.as_bool().unwrap();
} else if field_json.is_null() {
widget.value = String::new();
}
if field_name == "created_at" || field_name == "updated_at" {
widget.is_hide = false;
}
} else if !hash.is_empty() {
widget.widget = "hiddenText".to_string();
widget.input_type = "hidden".to_string();
widget.value = String::new();
}
widget_list.push(widget);
}
Ok(serde_json::to_string(&widget_list)?)
}
fn actix_instance_for_admin(
doc_hash: Option<&str>,
bytes: Option<&actix_web::web::BytesMut>,
filter: Option<&Document>,
options_json: Option<&str>,
) -> Result<OutputDataAdmin<Self>, Box<dyn Error>>
where
Self: serde::de::DeserializeOwned + Sized,
{
if doc_hash.is_some() {
let doc_hash = doc_hash.unwrap();
if doc_hash.is_empty() {
return Ok(OutputDataAdmin::EarlyResult(
Self::model_to_json_for_admin()?
));
}
let object_id = ObjectId::with_string(doc_hash);
if object_id.is_err() {
Err(format!(
"Model: `{}` > \
Method: `instance_for_admin` => \
Invalid document hash.",
Self::key()?
))?
}
let object_id = object_id.unwrap();
let filter = doc! {"_id": object_id};
Ok(OutputDataAdmin::Instance(Self::find_one_to_model_instance(
filter, None,
)?))
} else if bytes.is_some() {
Ok(OutputDataAdmin::Instance(Some(serde_json::from_slice::<
Self,
>(
&bytes.unwrap()
)?)))
} else if filter.is_some() {
Ok(OutputDataAdmin::Instance(Self::find_one_to_model_instance(
filter.unwrap().clone(),
None,
)?))
} else if options_json.is_some() {
Self::db_update_dyn_widgets(options_json.unwrap())?;
return Ok(OutputDataAdmin::EarlyResult(String::new()));
} else {
Err(format!(
"Model: `{}` > \
Method: `instance_for_admin` => \
No match on function arguments.",
Self::key()?
))?
}
}
fn actix_result_for_admin(
&mut self,
doc_hash: Option<&str>,
bytes: Option<&actix_web::web::BytesMut>,
filter: Option<&Document>,
) -> Result<String, Box<dyn Error>> {
if doc_hash.is_some() {
return self.instance_to_json_for_admin();
} else if bytes.is_some() {
let output_data = self.save(None, None)?;
return output_data.to_json_for_admin();
} else if filter.is_some() {
let output_data = self.delete(None)?;
if !output_data.is_valid() {
return Ok(output_data.err_msg());
}
} else {
Err(format!(
"Model: `{}` > \
Method: `result_for_admin` => \
No match on function arguments.",
Self::key()?
))?
}
Ok(String::new())
}
}