use serde::de::{Deserializer, MapAccess, Visitor};
use serde::ser::Serializer;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use std::collections::BTreeMap;
use std::fmt;
use std::ops::{Deref, DerefMut};
#[derive(Debug, Clone, Default, PartialEq)]
pub struct Extensions(pub BTreeMap<String, Value>);
impl Extensions {
pub fn new() -> Self {
Self::default()
}
pub fn get(&self, key: &str) -> Option<&Value> {
self.0.get(key)
}
pub fn contains_key(&self, key: &str) -> bool {
self.0.contains_key(key)
}
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
pub fn len(&self) -> usize {
self.0.len()
}
pub fn iter(&self) -> std::collections::btree_map::Iter<'_, String, Value> {
self.0.iter()
}
}
impl Deref for Extensions {
type Target = BTreeMap<String, Value>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for Extensions {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl Serialize for Extensions {
fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
self.0.serialize(s)
}
}
impl<'de> Deserialize<'de> for Extensions {
fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
struct ExtVisitor;
impl<'de> Visitor<'de> for ExtVisitor {
type Value = Extensions;
fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("a map of OAS specification extensions (`x-*` keys)")
}
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
where
A: MapAccess<'de>,
{
let mut out: BTreeMap<String, Value> = BTreeMap::new();
while let Some(key) = map.next_key::<String>()? {
let value: Value = map.next_value()?;
out.insert(key, value);
}
Ok(Extensions(out))
}
}
d.deserialize_map(ExtVisitor)
}
}
impl Extensions {
pub fn non_extension_keys(&self) -> impl Iterator<Item = &str> {
self.0
.keys()
.filter(|k| !k.starts_with("x-"))
.map(String::as_str)
}
}