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