use std::fmt;
use serde::{
Deserialize, Deserializer, Serialize, Serializer,
de::{MapAccess, Visitor},
ser::SerializeMap,
};
use crate::{
Map,
model::{extensions::Extensions, paths::item::PathItem, reference::RefOr},
};
#[derive(Clone, Debug, Default, PartialEq)]
pub struct Callback {
pub items: Map<RefOr<PathItem>>,
pub extensions: Extensions,
}
impl Callback {
#[must_use]
pub fn new() -> Self {
Self::default()
}
#[must_use]
pub fn with(mut self, expression: impl Into<String>, path_item: PathItem) -> Self {
self.items.insert(expression.into(), RefOr::Item(path_item));
self
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.items.is_empty() && self.extensions.is_empty()
}
}
impl Serialize for Callback {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
let mut map = serializer.serialize_map(Some(self.items.len() + self.extensions.0.len()))?;
for (expression, item) in &self.items {
map.serialize_entry(expression, item)?;
}
for (key, value) in &self.extensions.0 {
map.serialize_entry(key, value)?;
}
map.end()
}
}
impl<'de> Deserialize<'de> for Callback {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
struct CallbackVisitor;
impl<'de> Visitor<'de> for CallbackVisitor {
type Value = Callback;
fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("a map of runtime expressions to path items")
}
fn visit_map<A: MapAccess<'de>>(self, mut access: A) -> Result<Callback, A::Error> {
let mut callback = Callback::new();
while let Some(key) = access.next_key::<String>()? {
if key.starts_with(crate::model::extensions::EXTENSION_PREFIX) {
callback.extensions.0.insert(key, access.next_value()?);
} else {
callback.items.insert(key, access.next_value()?);
}
}
Ok(callback)
}
}
deserializer.deserialize_map(CallbackVisitor)
}
}