use std::marker::PhantomData;
use crate::*;
use indexmap::IndexMap;
use serde::{Deserialize, Deserializer, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
pub struct PathItem {
#[serde(skip_serializing_if = "Option::is_none")]
pub summary: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub get: Option<Operation>,
#[serde(skip_serializing_if = "Option::is_none")]
pub put: Option<Operation>,
#[serde(skip_serializing_if = "Option::is_none")]
pub post: Option<Operation>,
#[serde(skip_serializing_if = "Option::is_none")]
pub delete: Option<Operation>,
#[serde(skip_serializing_if = "Option::is_none")]
pub options: Option<Operation>,
#[serde(skip_serializing_if = "Option::is_none")]
pub head: Option<Operation>,
#[serde(skip_serializing_if = "Option::is_none")]
pub patch: Option<Operation>,
#[serde(skip_serializing_if = "Option::is_none")]
pub trace: Option<Operation>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub servers: Vec<Server>,
#[serde(default)]
#[serde(skip_serializing_if = "Vec::is_empty")]
pub parameters: Vec<ReferenceOr<Parameter>>,
#[serde(flatten, deserialize_with = "crate::util::deserialize_extensions")]
pub extensions: IndexMap<String, serde_json::Value>,
}
impl PathItem {
pub fn iter(&self) -> impl Iterator<Item = (&str, &'_ Operation)> {
vec![
("get", &self.get),
("put", &self.put),
("post", &self.post),
("delete", &self.delete),
("options", &self.options),
("head", &self.head),
("patch", &self.patch),
("trace", &self.trace),
]
.into_iter()
.filter_map(|(method, maybe_op)| maybe_op.as_ref().map(|op| (method, op)))
}
}
impl IntoIterator for PathItem {
type Item = (&'static str, Operation);
type IntoIter = std::vec::IntoIter<Self::Item>;
fn into_iter(self) -> Self::IntoIter {
vec![
("get", self.get),
("put", self.put),
("post", self.post),
("delete", self.delete),
("options", self.options),
("head", self.head),
("patch", self.patch),
("trace", self.trace),
]
.into_iter()
.filter_map(|(method, maybe_op)| maybe_op.map(|op| (method, op)))
.collect::<Vec<_>>()
.into_iter()
}
}
#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
pub struct Paths {
#[serde(flatten, deserialize_with = "deserialize_paths")]
pub paths: IndexMap<String, ReferenceOr<PathItem>>,
#[serde(flatten, deserialize_with = "crate::util::deserialize_extensions")]
pub extensions: IndexMap<String, serde_json::Value>,
}
impl Paths {
pub fn iter(&self) -> indexmap::map::Iter<String, ReferenceOr<PathItem>> {
self.paths.iter()
}
}
impl IntoIterator for Paths {
type Item = (String, ReferenceOr<PathItem>);
type IntoIter = indexmap::map::IntoIter<String, ReferenceOr<PathItem>>;
fn into_iter(self) -> Self::IntoIter {
self.paths.into_iter()
}
}
fn deserialize_paths<'de, D>(
deserializer: D,
) -> Result<IndexMap<String, ReferenceOr<PathItem>>, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_map(PredicateVisitor(
|key: &String| key.starts_with('/'),
PhantomData,
))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_path_item_iterators() {
let operation = Operation::default();
let path_item = PathItem {
get: Some(operation.clone()),
post: Some(operation.clone()),
delete: Some(operation.clone()),
..Default::default()
};
let expected = vec![
("get", &operation),
("post", &operation),
("delete", &operation),
];
assert_eq!(path_item.iter().collect::<Vec<_>>(), expected);
let expected = vec![
("get", operation.clone()),
("post", operation.clone()),
("delete", operation.clone()),
];
assert_eq!(path_item.into_iter().collect::<Vec<_>>(), expected);
}
}