use std::{collections::HashMap, rc::Rc};
use vertigo::DropFileItem;
use crate::{image_as_uri, nonify};
pub enum FieldExport {
Bool(bool),
String(String),
List(String),
Dict(i64),
Multi(Vec<i64>),
Image((Option<Rc<String>>, Option<DropFileItem>)),
}
#[derive(Clone)]
pub struct FormExport(Rc<HashMap<String, FieldExport>>);
impl FormExport {
pub fn new(map: HashMap<String, FieldExport>) -> Self {
Self(Rc::new(map))
}
pub fn get<'a>(&'a self, key: &str) -> Option<&'a FieldExport> {
self.0.get(key)
}
pub fn get_string(&self, key: &str) -> String {
self.get_string_opt(key).unwrap_or_default()
}
pub fn get_string_opt(&self, key: &str) -> Option<String> {
self.get(key).and_then(|export| {
if let FieldExport::String(val) = export {
nonify(val.clone())
} else {
None
}
})
}
pub fn list<T: From<String>>(&self, key: &str) -> Option<T> {
self.get(key).and_then(|export| {
if let FieldExport::List(val) = export {
nonify(val.clone()).map(Into::into)
} else {
None
}
})
}
pub fn list_or_default<T: Default + From<String>>(&self, key: &str) -> T {
self.list(key).unwrap_or_default()
}
pub fn dict_or_default<T: From<i64>>(&self, key: &str) -> T {
self.get(key)
.map(|export| {
if let FieldExport::Dict(val) = export {
*val
} else {
Default::default()
}
})
.unwrap_or_default()
.into()
}
pub fn multi<T: From<i64>>(&self, key: &str) -> Vec<T> {
self.get(key)
.map(|export| {
if let FieldExport::Multi(val) = export {
val.iter().cloned().map(Into::into).collect()
} else {
Default::default()
}
})
.unwrap_or_default()
}
pub fn get_bool(&self, key: &str) -> bool {
self.get_bool_opt(key).unwrap_or_default()
}
pub fn get_bool_opt(&self, key: &str) -> Option<bool> {
self.get(key).and_then(|export| {
if let FieldExport::Bool(val) = export {
Some(*val)
} else {
None
}
})
}
pub fn image_url(&self, key: &str) -> String {
self.image_url_opt(key).unwrap_or_default()
}
pub fn image_url_opt(&self, key: &str) -> Option<String> {
if let Some(export) = self.get(key) {
match export {
FieldExport::Image((orig_link, dfi)) => dfi
.as_ref()
.map(image_as_uri)
.or_else(|| orig_link.as_ref().map(|ol| ol.to_string())),
_ => None,
}
} else {
None
}
}
pub fn image_item_opt(&self, key: &str) -> Option<DropFileItem> {
if let Some(export) = self.get(key) {
match export {
FieldExport::Image((_orig_link, dfi)) => dfi.clone(),
_ => None,
}
} else {
None
}
}
pub fn image_orig_url_opt(&self, key: &str) -> Option<Rc<String>> {
if let Some(export) = self.get(key) {
match export {
FieldExport::Image((orig_link, _dfi)) => orig_link.clone(),
_ => None,
}
} else {
None
}
}
}