tag2upload_service_manager/
ui_abstract.rs1
2use crate::prelude::*;
3
4pub trait UiDisplay {
6 fn ui_display(&self) -> Cow<'_, str>;
7}
8
9pub trait UiMap {
17 fn ui_serialize(&self) -> HashMap<&str, Cow<'_, str>> {
18 let mut map = HashMap::new();
19 map.extend(self.ui_fields());
20 map
21 }
22
23 fn ui_fields(&self) -> impl Iterator<Item = (&str, Cow<'_, str>)>;
24}
25
26pub struct UiSerializeMap<T>(pub T);
27
28impl<T: UiMap> Serialize for UiSerializeMap<T> {
29 fn serialize<S: Serializer>(&self, ser: S) -> Result<S::Ok, S::Error> {
30 self.0
31 .ui_serialize()
32 .serialize(ser)
33 }
34}
35
36pub struct UiSerializeRows<R>(pub Vec<R>);
37
38impl<R: UiMap> Serialize for UiSerializeRows<R> {
39 fn serialize<S: Serializer>(&self, ser: S) -> Result<S::Ok, S::Error> {
40 self.0.iter().map(|row| row.ui_serialize())
41 .collect_vec()
42 .serialize(ser)
43 }
44}
45
46define_derive_deftly! {
47 UiMap expect items:
53
54 impl $crate::ui_abstract::UiMap for $ttype {
55 fn ui_fields(&self) -> impl Iterator<Item = (&str, Cow<'_, str>)> {
56 use $crate::ui_abstract::*;
57
58 chain!(
59 $(
60 ${select1
61 fmeta(ui(flatten)) {
62 <$ftype as UiMap>::ui_fields(&self.$fname),
63 }
64 fmeta(ui(skip)) {
65 }
66 else {
67 [(
68 stringify!($fname),
69 <$ftype as UiDisplay>::ui_display(&self.$fname),
70 )],
71 }
72 }
73 )
74 )
75 }
76 }
77}
78
79define_derive_deftly! {
80 UiDisplayEnum for enum, expect items:
82
83 impl $crate::ui_abstract::UiDisplay for $ttype {
84 fn ui_display(&self) -> Cow<'_, str> {
85 match self {
86 $(
87 ${if v_is_unit {
88 $tname::$vname {} => Cow::Borrowed(stringify!($vname))
89 } else {
90 $tname::$vname(inner) => {
91 $crate::ui_abstract::UiDisplay::ui_display(inner)
92 }
93 }},
94 )
95 }
96 }
97 }
98}
99
100impl UiDisplay for String {
101 fn ui_display(&self) -> Cow<'_, str> { Cow::Borrowed(self) }
102}
103
104impl<T: UiDisplay + SuitableForNoneIsEmpty> UiDisplay for NoneIsEmpty<T> {
105 fn ui_display(&self) -> Cow<'_, str> {
106 self.as_ref().map(|v| v.ui_display()).unwrap_or_default()
107 }
108}
109
110impl<T: UiDisplay> UiDisplay for Option<T> {
111 fn ui_display(&self) -> Cow<'_, str> {
112 self.as_ref().map(|v| v.ui_display()).unwrap_or_default()
113 }
114}
115
116#[macro_export]
118macro_rules! ui_display_via_to_string { { $( $ty:ty )* } => { $(
119 impl $crate::ui_abstract::UiDisplay for $ty {
120 fn ui_display(&self) -> Cow<'_, str> { Cow::Owned(self.to_string()) }
121 }
122)* } }
123
124ui_display_via_to_string! { bool u32 i64 }