1use serde::{Deserialize, Deserializer, Serialize, Serializer};
2
3use once_cell::sync::Lazy;
4
5use std::{
6 cmp::Ordering,
7 collections::BTreeMap,
8 fmt,
9 ops::{Deref, DerefMut},
10 sync::Arc,
11};
12
13pub static JSON_MIME: Lazy<MediaRange> =
15 Lazy::new(|| MediaRange("application/json".parse().expect("parsing mime")));
16pub static JSON_CODER: Lazy<Arc<Coder>> = Lazy::new(|| {
18 Arc::new(Coder {
19 encoder_path: "serde_json::to_writer".into(),
20 decoder_path: "serde_json::from_reader".into(),
21 any_value: "serde_json::Value".into(),
22 error_path: "serde_json::Error".into(),
23 prefer: false,
24 builtin: true,
25 })
26});
27pub static YAML_MIME: Lazy<MediaRange> =
29 Lazy::new(|| MediaRange("application/yaml".parse().expect("parsing mime")));
30pub static YAML_CODER: Lazy<Arc<Coder>> = Lazy::new(|| {
32 Arc::new(Coder {
33 encoder_path: "serde_yaml::to_writer".into(),
34 decoder_path: "serde_yaml::from_reader".into(),
35 any_value: "serde_yaml::Value".into(),
36 error_path: "serde_yaml::Error".into(),
37 prefer: false,
38 builtin: true,
39 })
40});
41
42#[derive(Debug, Clone)]
44pub struct MediaRange(pub mime::Mime);
45
46#[cfg(feature = "codegen")]
47impl MediaRange {
48 fn matches_params(&self, r: &Self) -> bool {
50 for (name, value) in self.0.params() {
51 if name != "q" && r.0.get_param(name) != Some(value) {
52 return false;
53 }
54 }
55
56 true
57 }
58}
59
60#[derive(Debug, Default, Clone)]
62pub struct Coders(BTreeMap<MediaRange, Arc<Coder>>);
63
64#[cfg(feature = "codegen")]
65impl Coders {
66 pub fn matching_coder(&self, ty: &MediaRange) -> Option<Arc<Coder>> {
70 self.0
71 .get(ty)
72 .or_else(|| {
73 let (target_t1, target_t2) = (ty.0.type_(), ty.0.subtype());
74 for (r, c) in &self.0 {
75 let (source_t1, source_t2) = (r.0.type_(), r.0.subtype());
76 if target_t1 == mime::STAR && r.matches_params(ty) {
77 return Some(c);
78 }
79
80 if source_t1 != target_t1 {
81 continue;
82 }
83
84 if target_t2 == mime::STAR && r.matches_params(ty) {
85 return Some(c);
86 }
87
88 if source_t2 != target_t2 {
89 continue;
90 }
91
92 return Some(c);
93 }
94
95 None
96 })
97 .map(Clone::clone)
98 }
99}
100
101#[derive(Debug, Default, Clone, Serialize, Deserialize)]
103pub struct Coder {
104 pub encoder_path: String,
106 pub decoder_path: String,
108 pub error_path: String,
110 pub any_value: String,
112 #[serde(default)]
116 pub prefer: bool,
117 #[serde(skip)]
119 pub builtin: bool,
120}
121
122impl PartialEq for MediaRange {
125 fn eq(&self, other: &MediaRange) -> bool {
126 self.0.eq(&other.0)
127 }
128}
129
130impl Eq for MediaRange {}
131
132impl PartialOrd for MediaRange {
133 fn partial_cmp(&self, other: &MediaRange) -> Option<Ordering> {
134 Some(self.cmp(other))
135 }
136}
137
138impl Ord for MediaRange {
139 fn cmp(&self, other: &MediaRange) -> Ordering {
140 self.0.as_ref().cmp(other.0.as_ref())
141 }
142}
143
144impl Serialize for MediaRange {
145 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
146 where
147 S: Serializer,
148 {
149 serializer.serialize_str(self.0.as_ref())
150 }
151}
152
153impl<'de> Deserialize<'de> for MediaRange {
154 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
155 where
156 D: Deserializer<'de>,
157 {
158 struct Visitor;
159
160 impl serde::de::Visitor<'_> for Visitor {
161 type Value = MediaRange;
162
163 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
164 f.write_str("a valid media range")
165 }
166
167 fn visit_str<E>(self, value: &str) -> Result<MediaRange, E>
168 where
169 E: serde::de::Error,
170 {
171 value.parse().map_err(E::custom).map(MediaRange)
172 }
173 }
174
175 deserializer.deserialize_str(Visitor)
176 }
177}
178
179impl Deref for Coders {
180 type Target = BTreeMap<MediaRange, Arc<Coder>>;
181
182 fn deref(&self) -> &Self::Target {
183 &self.0
184 }
185}
186
187impl DerefMut for Coders {
188 fn deref_mut(&mut self) -> &mut <Self as Deref>::Target {
189 &mut self.0
190 }
191}
192
193impl Serialize for Coders {
194 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
195 where
196 S: Serializer,
197 {
198 self.0.serialize(serializer)
199 }
200}
201
202impl<'de> Deserialize<'de> for Coders {
203 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
204 where
205 D: Deserializer<'de>,
206 {
207 Ok(Coders(BTreeMap::deserialize(deserializer)?))
208 }
209}
210
211pub(crate) fn deserialize_extensions<'de, D>(
215 deserializer: D,
216) -> Result<BTreeMap<String, serde_json::Value>, D::Error>
217where
218 D: Deserializer<'de>,
219{
220 deserializer.deserialize_map(PredicateVisitor(
221 |key: &String| key.starts_with("x-"),
222 std::marker::PhantomData,
223 ))
224}
225
226pub(crate) struct PredicateVisitor<F, K, V>(pub F, pub std::marker::PhantomData<(K, V)>);
230
231impl<'de, F, K, V> serde::de::Visitor<'de> for PredicateVisitor<F, K, V>
232where
233 F: Fn(&K) -> bool,
234 K: Deserialize<'de> + Eq + std::hash::Hash + std::cmp::Ord,
235 V: Deserialize<'de>,
236{
237 type Value = BTreeMap<K, V>;
238
239 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
240 formatter.write_str("a map whose fields obey a predicate")
241 }
242
243 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
244 where
245 A: serde::de::MapAccess<'de>,
246 {
247 let mut ret = Self::Value::default();
248
249 loop {
250 match map.next_key::<K>() {
251 Err(_) => (),
252 Ok(None) => break,
253 Ok(Some(key)) if self.0(&key) => {
254 let _ = ret.insert(key, map.next_value()?);
255 }
256 Ok(Some(_)) => {
257 let _ = map.next_value::<serde::de::IgnoredAny>()?;
258 }
259 }
260 }
261
262 Ok(ret)
263 }
264}