1use std::{
2 collections::HashMap,
3 error::Error,
4 fmt::{Debug, Display},
5 ops::{Deref, DerefMut},
6};
7
8use serde::{Deserialize, Deserializer, Serialize, Serializer, ser::SerializeMap};
9
10#[cfg_attr(feature = "salvo", derive(salvo::prelude::ToSchema))]
11#[derive(Debug, Default)]
12pub(crate) struct OrderedHashMap<K, V>(pub(crate) HashMap<K, V>);
13
14impl<K, V> Serialize for OrderedHashMap<K, V>
15where
16 K: Serialize + Ord,
17 V: Serialize,
18{
19 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
20 where
21 S: Serializer,
22 {
23 let mut sorted_entries: Vec<_> = self.0.iter().collect();
24 sorted_entries.sort_by_key(|&(k, _)| k);
25
26 let mut map = serializer.serialize_map(Some(sorted_entries.len()))?;
27 for (k, v) in sorted_entries {
28 map.serialize_entry(k, v)?;
29 }
30 map.end()
31 }
32}
33
34impl<'de, K, V> Deserialize<'de> for OrderedHashMap<K, V>
35where
36 K: Deserialize<'de> + Eq + std::hash::Hash,
37 V: Deserialize<'de>,
38{
39 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
40 where
41 D: Deserializer<'de>,
42 {
43 let map = HashMap::deserialize(deserializer)?;
44 Ok(OrderedHashMap(map))
45 }
46}
47
48impl<K, V> Deref for OrderedHashMap<K, V> {
49 type Target = HashMap<K, V>;
50
51 fn deref(&self) -> &Self::Target {
52 &self.0
53 }
54}
55
56impl<K, V> DerefMut for OrderedHashMap<K, V> {
57 fn deref_mut(&mut self) -> &mut Self::Target {
58 &mut self.0
59 }
60}
61
62#[derive(Clone, PartialEq, Eq, Debug, Hash)]
63#[non_exhaustive]
64pub enum MaybeString {
65 String(String),
66 Str(&'static str),
67 OptionString(Option<String>),
68 OptionStr(Option<&'static str>),
69 UnitTuple,
70}
71impl From<()> for MaybeString {
72 fn from(_: ()) -> Self {
73 MaybeString::UnitTuple
74 }
75}
76impl From<String> for MaybeString {
77 fn from(value: String) -> Self {
78 MaybeString::String(value)
79 }
80}
81impl From<&'static str> for MaybeString {
82 fn from(value: &'static str) -> Self {
83 MaybeString::Str(value)
84 }
85}
86impl From<Option<String>> for MaybeString {
87 fn from(value: Option<String>) -> Self {
88 MaybeString::OptionString(value)
89 }
90}
91impl From<Option<&'static str>> for MaybeString {
92 fn from(value: Option<&'static str>) -> Self {
93 MaybeString::OptionStr(value)
94 }
95}
96impl MaybeString {
97 pub fn option_string(self) -> Option<String> {
98 match self {
99 MaybeString::String(v) => Some(v),
100 MaybeString::Str(v) => Some(v.to_owned()),
101 MaybeString::OptionString(v) => v,
102 MaybeString::OptionStr(v) => v.map(ToOwned::to_owned),
103 MaybeString::UnitTuple => None,
104 }
105 }
106 pub fn expect(self, msg: &str) -> String {
109 match self {
110 MaybeString::String(v) => v,
111 MaybeString::Str(v) => v.to_owned(),
112 MaybeString::OptionString(v) => v.expect(msg),
113 MaybeString::OptionStr(v) => v.expect(msg).to_owned(),
114 MaybeString::UnitTuple => panic!("{msg}"),
115 }
116 }
117 pub fn unwrap_or(self, default: impl Into<String>) -> String {
118 match self {
119 MaybeString::String(v) => v,
120 MaybeString::Str(v) => v.to_owned(),
121 MaybeString::OptionString(v) => v.unwrap_or_else(|| default.into()),
122 MaybeString::OptionStr(v) => v.map_or_else(|| default.into(), ToOwned::to_owned),
123 MaybeString::UnitTuple => default.into(),
124 }
125 }
126 pub fn unwrap_or_else(self, f: impl FnOnce() -> String) -> String {
127 match self {
128 MaybeString::String(v) => v,
129 MaybeString::Str(v) => v.to_owned(),
130 MaybeString::OptionString(v) => v.unwrap_or_else(f),
131 MaybeString::OptionStr(v) => v.map_or_else(f, ToOwned::to_owned),
132 MaybeString::UnitTuple => f(),
133 }
134 }
135 pub fn unwrap_or_default(self) -> String {
136 match self {
137 MaybeString::String(v) => v,
138 MaybeString::Str(v) => v.to_owned(),
139 MaybeString::OptionString(v) => v.unwrap_or_default(),
140 MaybeString::OptionStr(v) => v.map_or_else(Default::default, ToOwned::to_owned),
141 MaybeString::UnitTuple => String::default(),
142 }
143 }
144}
145impl From<MaybeString> for Option<String> {
146 fn from(value: MaybeString) -> Self {
147 value.option_string()
148 }
149}
150
151#[derive(Debug)]
152#[non_exhaustive]
153pub struct ErrWrapper<E: Display>(pub E);
154
155impl<E: Debug + Display> Display for ErrWrapper<E> {
156 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
157 Display::fmt(&self.0, f)
158 }
159}
160
161impl<E: Debug + Display> Error for ErrWrapper<E> {}
162
163pub trait IntoError: Debug + Display + Sized {
164 fn into_error(self) -> ErrWrapper<Self> {
165 ErrWrapper(self)
166 }
167}
168
169impl<E: Debug + Display + Sized> IntoError for E {}
170
171#[cfg(test)]
172mod tests {
173 use std::{collections::HashMap, error::Error};
174
175 use super::{IntoError, OrderedHashMap};
176
177 #[test]
178 fn ordered_hash_map() {
179 const S: &str = r#"{"k1":"v1","k2":"v2"}"#;
180 let mut map = HashMap::new();
181 map.insert("k2", "v2");
182 map.insert("k1", "v1");
183 let map1 = OrderedHashMap(map);
184 assert_eq!(S, serde_json::to_string(&map1).unwrap());
185 let map2: OrderedHashMap<&str, &str> = serde_json::from_str(S).unwrap();
186 assert_eq!(S, serde_json::to_string(&map2).unwrap());
187 }
188
189 #[test]
190 fn error_wrapper() {
191 let e: super::ErrWrapper<u32> = 1.into_error();
192 let d: &dyn Error = &e;
193 assert_eq!("1", d.to_string())
194 }
195}