tag2upload_service_manager/
ui_abstract.rs
use crate::prelude::*;
pub trait UiDisplay {
fn ui_display(&self) -> Cow<str>;
}
pub trait UiMap {
fn ui_serialize(&self) -> HashMap<&str, Cow<str>> {
let mut map = HashMap::new();
map.extend(self.ui_fields());
map
}
fn ui_fields(&self) -> impl Iterator<Item = (&str, Cow<str>)>;
}
pub struct UiSerializeRows<R>(pub Vec<R>);
impl<R: UiMap> Serialize for UiSerializeRows<R> {
fn serialize<S: Serializer>(&self, ser: S) -> Result<S::Ok, S::Error> {
self.0.iter().map(|row| row.ui_serialize())
.collect_vec()
.serialize(ser)
}
}
define_derive_deftly! {
UiMap expect items:
impl $crate::ui_abstract::UiMap for $ttype {
fn ui_fields(&self) -> impl Iterator<Item = (&str, Cow<str>)> {
use $crate::ui_abstract::*;
chain!(
$(
${select1
fmeta(ui(flatten)) {
<$ftype as UiMap>::ui_fields(&self.$fname),
}
fmeta(ui(skip)) {
}
else {
[(
stringify!($fname),
<$ftype as UiDisplay>::ui_display(&self.$fname),
)],
}
}
)
)
}
}
}
define_derive_deftly! {
UiDisplayEnum for enum, expect items:
impl $crate::ui_abstract::UiDisplay for $ttype {
fn ui_display(&self) -> Cow<str> {
match self {
$(
$tname::$vname {} => Cow::Borrowed(stringify!($vname)),
)
}
}
}
}
impl UiDisplay for String {
fn ui_display(&self) -> Cow<str> { Cow::Borrowed(self) }
}
impl<T: UiDisplay + SuitableForNoneIsEmpty> UiDisplay for NoneIsEmpty<T> {
fn ui_display(&self) -> Cow<str> {
self.as_ref().map(|v| v.ui_display()).unwrap_or_default()
}
}
impl<T: UiDisplay> UiDisplay for Option<T> {
fn ui_display(&self) -> Cow<str> {
self.as_ref().map(|v| v.ui_display()).unwrap_or_default()
}
}
#[macro_export]
macro_rules! ui_display_via_to_string { { $( $ty:ty )* } => { $(
impl $crate::ui_abstract::UiDisplay for $ty {
fn ui_display(&self) -> Cow<str> { Cow::Owned(self.to_string()) }
}
)* } }
ui_display_via_to_string! { i64 }