openapi_to_rust/
extensions.rs1use serde::de::{Deserializer, MapAccess, Visitor};
25use serde::ser::Serializer;
26use serde::{Deserialize, Serialize};
27use serde_json::Value;
28use std::collections::BTreeMap;
29use std::fmt;
30use std::ops::{Deref, DerefMut};
31
32#[derive(Debug, Clone, Default, PartialEq)]
34pub struct Extensions(pub BTreeMap<String, Value>);
35
36impl Extensions {
37 pub fn new() -> Self {
38 Self::default()
39 }
40
41 pub fn get(&self, key: &str) -> Option<&Value> {
42 self.0.get(key)
43 }
44
45 pub fn contains_key(&self, key: &str) -> bool {
46 self.0.contains_key(key)
47 }
48
49 pub fn is_empty(&self) -> bool {
50 self.0.is_empty()
51 }
52
53 pub fn len(&self) -> usize {
54 self.0.len()
55 }
56
57 pub fn iter(&self) -> std::collections::btree_map::Iter<'_, String, Value> {
58 self.0.iter()
59 }
60}
61
62impl Deref for Extensions {
63 type Target = BTreeMap<String, Value>;
64 fn deref(&self) -> &Self::Target {
65 &self.0
66 }
67}
68
69impl DerefMut for Extensions {
70 fn deref_mut(&mut self) -> &mut Self::Target {
71 &mut self.0
72 }
73}
74
75impl Serialize for Extensions {
76 fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
77 self.0.serialize(s)
78 }
79}
80
81impl<'de> Deserialize<'de> for Extensions {
82 fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
83 struct ExtVisitor;
84
85 impl<'de> Visitor<'de> for ExtVisitor {
86 type Value = Extensions;
87
88 fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
89 f.write_str("a map of extension and compatibility fields")
90 }
91
92 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
93 where
94 A: MapAccess<'de>,
95 {
96 let mut out: BTreeMap<String, Value> = BTreeMap::new();
102 while let Some(key) = map.next_key::<String>()? {
103 let value: Value = map.next_value()?;
104 out.insert(key, value);
105 }
106 Ok(Extensions(out))
107 }
108 }
109
110 d.deserialize_map(ExtVisitor)
111 }
112}
113
114impl Extensions {
115 pub fn non_extension_keys(&self) -> impl Iterator<Item = &str> {
120 self.0
121 .keys()
122 .filter(|k| !k.starts_with("x-"))
123 .map(String::as_str)
124 }
125}