1use std::hash::Hash;
2use std::marker::PhantomData;
3
4use indexmap::IndexMap;
5use serde::{
6 de::{IgnoredAny, Visitor},
7 Deserialize, Deserializer,
8};
9
10#[allow(clippy::trivially_copy_pass_by_ref)] #[inline]
12pub const fn is_false(v: &bool) -> bool {
13 !(*v)
14}
15
16pub(crate) fn deserialize_extensions<'de, D>(
17 deserializer: D,
18) -> Result<IndexMap<String, serde_json::Value>, D::Error>
19where
20 D: Deserializer<'de>,
21{
22 deserializer.deserialize_map(PredicateVisitor(
23 |key: &String| key.starts_with("x-"),
24 PhantomData,
25 ))
26}
27
28pub(crate) struct PredicateVisitor<F, K, V>(pub F, pub PhantomData<(K, V)>);
31
32impl<'de, F, K, V> Visitor<'de> for PredicateVisitor<F, K, V>
33where
34 F: Fn(&K) -> bool,
35 K: Deserialize<'de> + Eq + Hash,
36 V: Deserialize<'de>,
37{
38 type Value = IndexMap<K, V>;
39
40 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
41 formatter.write_str("a map whose fields obey a predicate")
42 }
43
44 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
45 where
46 A: serde::de::MapAccess<'de>,
47 {
48 let mut ret = Self::Value::default();
49
50 loop {
51 match map.next_key::<K>() {
52 Err(_) => (),
53 Ok(None) => break,
54 Ok(Some(key)) if self.0(&key) => {
55 let _ = ret.insert(key, map.next_value()?);
56 }
57 Ok(Some(_)) => {
58 let _ = map.next_value::<IgnoredAny>()?;
59 }
60 }
61 }
62
63 Ok(ret)
64 }
65}