1use indexmap::IndexMap;
2use serde::{Deserialize, Deserializer, de::DeserializeOwned};
3
4#[inline]
5pub fn deserialize_defaultable<'de, T, D>(deserializer: D) -> Result<T, D::Error>
6where
7 T: DeserializeOwned + Default,
8 D: Deserializer<'de>,
9{
10 let value = serde_json::Value::deserialize(deserializer)?;
11
12 Ok(serde_json::from_value(value).unwrap_or_default())
13}
14
15pub fn deserialize_stringable_option<'de, D>(deserializer: D) -> Result<Option<String>, D::Error>
16where
17 D: Deserializer<'de>,
18{
19 let value = serde_json::Value::deserialize(deserializer).unwrap_or_default();
20 Ok(match value {
21 serde_json::Value::Null => None,
22 serde_json::Value::String(string) if string.is_empty() => None,
23 serde_json::Value::String(string) => Some(string),
24 value => Some(value.to_string()),
25 })
26}
27
28pub fn deserialize_string_option<'de, D>(
29 deserializer: D,
30) -> Result<Option<compact_str::CompactString>, D::Error>
31where
32 D: Deserializer<'de>,
33{
34 let value: Option<compact_str::CompactString> =
35 Option::deserialize(deserializer).unwrap_or_default();
36 Ok(value.filter(|s| !s.is_empty()))
37}
38
39pub fn deserialize_array_or_not<'de, D, T: DeserializeOwned>(
40 deserializer: D,
41) -> Result<Vec<T>, D::Error>
42where
43 D: Deserializer<'de>,
44{
45 let value = serde_json::Value::deserialize(deserializer).unwrap_or_default();
46 let value: Vec<T> = match value {
47 serde_json::Value::Array(values) => {
48 serde_json::from_value(serde_json::Value::Array(values))
49 .map_err(serde::de::Error::custom)?
50 }
51 value => vec![serde_json::from_value(value).map_err(serde::de::Error::custom)?],
52 };
53
54 Ok(value)
55}
56
57pub fn deserialize_map_or_not<
58 'de,
59 D,
60 K: DeserializeOwned + std::hash::Hash + Eq,
61 V: DeserializeOwned,
62>(
63 deserializer: D,
64) -> Result<IndexMap<K, V>, D::Error>
65where
66 D: Deserializer<'de>,
67{
68 let value = serde_json::Value::deserialize(deserializer).unwrap_or_default();
69 let value: IndexMap<K, V> = match value {
70 serde_json::Value::Object(map) => serde_json::from_value(serde_json::Value::Object(map))
71 .map_err(serde::de::Error::custom)?,
72 value => {
73 let v = serde_json::from_value(value).map_err(serde::de::Error::custom)?;
74 let mut map = IndexMap::new();
75 map.insert(
76 K::deserialize(serde_json::Value::String("Default".into()))
77 .map_err(serde::de::Error::custom)?,
78 v,
79 );
80 map
81 }
82 };
83
84 Ok(value)
85}
86
87pub fn deserialize_pre_stringified<'de, D, T: DeserializeOwned>(
88 deserializer: D,
89) -> Result<T, D::Error>
90where
91 D: Deserializer<'de>,
92{
93 let value: serde_json::Value = serde_json::Value::deserialize(deserializer)?;
94 let value: T = match value {
95 serde_json::Value::String(value) => {
96 serde_json::from_str(&value).map_err(serde::de::Error::custom)?
97 }
98 value => serde_json::from_value(value).map_err(serde::de::Error::custom)?,
99 };
100
101 Ok(value)
102}
103
104pub fn deserialize_nest_egg_config_stop<'de, D>(
105 deserializer: D,
106) -> Result<crate::models::nest_egg::NestEggConfigStop, D::Error>
107where
108 D: Deserializer<'de>,
109{
110 let value: serde_json::Value = serde_json::Value::deserialize(deserializer)?;
111 let value: crate::models::nest_egg::NestEggConfigStop = match value {
112 serde_json::Value::String(value) => serde_json::from_str(&value).unwrap_or_else(|_| {
113 crate::models::nest_egg::NestEggConfigStop {
114 r#type: if value == "^C" || value == "^^C" {
115 "signal".into()
116 } else {
117 "command".into()
118 },
119 value: Some(match value.as_str() {
120 "^C" => "SIGINT".into(),
121 "^^C" => "SIGKILL".into(),
122 _ => value.into(),
123 }),
124 }
125 }),
126 value => serde_json::from_value(value).map_err(serde::de::Error::custom)?,
127 };
128
129 Ok(value)
130}
131
132pub fn deserialize_nest_egg_config_files<'de, D>(
133 deserializer: D,
134) -> Result<
135 IndexMap<compact_str::CompactString, crate::models::nest_egg::ExportedNestEggConfigsFilesFile>,
136 D::Error,
137>
138where
139 D: Deserializer<'de>,
140{
141 let value: serde_json::Value = serde_json::Value::deserialize(deserializer)?;
142 let value: serde_json::Value = match value {
143 serde_json::Value::String(value) => serde_json::from_str(&value).unwrap_or_default(),
144 value => value,
145 };
146
147 #[derive(Deserialize, Clone)]
148 pub struct OldExportedNestEggConfigsFilesFile {
149 pub parser: crate::models::nest_egg::ServerConfigurationFileParser,
150 pub find: IndexMap<compact_str::CompactString, serde_json::Value>,
151 }
152
153 if let Ok(value) = serde_json::from_value::<
154 IndexMap<compact_str::CompactString, OldExportedNestEggConfigsFilesFile>,
155 >(value.clone())
156 {
157 Ok(value
158 .into_iter()
159 .map(|(k, v)| {
160 (
161 k,
162 crate::models::nest_egg::ExportedNestEggConfigsFilesFile {
163 create_new: true,
164 parser: v.parser,
165 replace: v
166 .find
167 .into_iter()
168 .map(|(k, replace_with)| {
169 crate::models::nest_egg::ProcessConfigurationFileReplacement {
170 r#match: k,
171 insert_new: !matches!(v.parser, crate::models::nest_egg::ServerConfigurationFileParser::File),
172 update_existing: true,
173 if_value: None,
174 replace_with,
175 }
176 })
177 .collect(),
178 },
179 )
180 })
181 .collect())
182 } else {
183 serde_json::from_value(value).map_err(serde::de::Error::custom)
184 }
185}
186
187pub fn deserialize_nest_egg_variable_rules<'de, D>(
188 deserializer: D,
189) -> Result<Vec<compact_str::CompactString>, D::Error>
190where
191 D: Deserializer<'de>,
192{
193 let value: serde_json::Value = serde_json::Value::deserialize(deserializer)?;
194 let value: Vec<compact_str::CompactString> = match value {
195 serde_json::Value::String(value) => value.split('|').map(|v| v.into()).collect(),
196 value => serde_json::from_value(value).map_err(serde::de::Error::custom)?,
197 };
198
199 Ok(value)
200}
201
202pub fn deserialize_public_key<'de, D>(deserializer: D) -> Result<russh::keys::PublicKey, D::Error>
203where
204 D: Deserializer<'de>,
205{
206 let value = <&str>::deserialize(deserializer)?;
207 let public_key = russh::keys::PublicKey::from_openssh(value)
208 .map_err(|_| serde::de::Error::custom("invalid public key"))?;
209
210 Ok(public_key)
211}