1use std::marker::PhantomData;
2
3use crate::*;
4use indexmap::IndexMap;
5use serde::{Deserialize, Deserializer, Serialize};
6
7#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
13pub struct PathItem {
14 #[serde(skip_serializing_if = "Option::is_none")]
17 pub summary: Option<String>,
18 #[serde(skip_serializing_if = "Option::is_none")]
21 pub description: Option<String>,
22 #[serde(skip_serializing_if = "Option::is_none")]
23 pub get: Option<Operation>,
24 #[serde(skip_serializing_if = "Option::is_none")]
25 pub put: Option<Operation>,
26 #[serde(skip_serializing_if = "Option::is_none")]
27 pub post: Option<Operation>,
28 #[serde(skip_serializing_if = "Option::is_none")]
29 pub delete: Option<Operation>,
30 #[serde(skip_serializing_if = "Option::is_none")]
31 pub options: Option<Operation>,
32 #[serde(skip_serializing_if = "Option::is_none")]
33 pub head: Option<Operation>,
34 #[serde(skip_serializing_if = "Option::is_none")]
35 pub patch: Option<Operation>,
36 #[serde(skip_serializing_if = "Option::is_none")]
37 pub trace: Option<Operation>,
38 #[serde(default, skip_serializing_if = "Vec::is_empty")]
40 pub servers: Vec<Server>,
41 #[serde(default)]
49 #[serde(skip_serializing_if = "Vec::is_empty")]
50 pub parameters: Vec<ReferenceOr<Parameter>>,
51 #[serde(flatten, deserialize_with = "crate::util::deserialize_extensions")]
53 pub extensions: IndexMap<String, serde_json::Value>,
54}
55
56impl PathItem {
57 pub fn iter(&self) -> impl Iterator<Item = (&str, &'_ Operation)> {
59 vec![
60 ("get", &self.get),
61 ("put", &self.put),
62 ("post", &self.post),
63 ("delete", &self.delete),
64 ("options", &self.options),
65 ("head", &self.head),
66 ("patch", &self.patch),
67 ("trace", &self.trace),
68 ]
69 .into_iter()
70 .filter_map(|(method, maybe_op)| maybe_op.as_ref().map(|op| (method, op)))
71 }
72}
73
74impl IntoIterator for PathItem {
75 type Item = (&'static str, Operation);
76
77 type IntoIter = std::vec::IntoIter<Self::Item>;
78
79 fn into_iter(self) -> Self::IntoIter {
81 vec![
82 ("get", self.get),
83 ("put", self.put),
84 ("post", self.post),
85 ("delete", self.delete),
86 ("options", self.options),
87 ("head", self.head),
88 ("patch", self.patch),
89 ("trace", self.trace),
90 ]
91 .into_iter()
92 .filter_map(|(method, maybe_op)| maybe_op.map(|op| (method, op)))
93 .collect::<Vec<_>>()
94 .into_iter()
95 }
96}
97
98#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
103pub struct Paths {
104 #[serde(flatten, deserialize_with = "deserialize_paths")]
106 pub paths: IndexMap<String, ReferenceOr<PathItem>>,
107 #[serde(flatten, deserialize_with = "crate::util::deserialize_extensions")]
109 pub extensions: IndexMap<String, serde_json::Value>,
110}
111
112impl Paths {
113 pub fn iter(&self) -> indexmap::map::Iter<String, ReferenceOr<PathItem>> {
115 self.paths.iter()
116 }
117}
118
119impl IntoIterator for Paths {
120 type Item = (String, ReferenceOr<PathItem>);
121
122 type IntoIter = indexmap::map::IntoIter<String, ReferenceOr<PathItem>>;
123
124 fn into_iter(self) -> Self::IntoIter {
125 self.paths.into_iter()
126 }
127}
128
129fn deserialize_paths<'de, D>(
130 deserializer: D,
131) -> Result<IndexMap<String, ReferenceOr<PathItem>>, D::Error>
132where
133 D: Deserializer<'de>,
134{
135 deserializer.deserialize_map(PredicateVisitor(
136 |key: &String| key.starts_with('/'),
137 PhantomData,
138 ))
139}
140
141#[cfg(test)]
142mod tests {
143 use super::*;
144
145 #[test]
146 fn test_path_item_iterators() {
147 let operation = Operation::default();
148
149 let path_item = PathItem {
150 get: Some(operation.clone()),
151 post: Some(operation.clone()),
152 delete: Some(operation.clone()),
153 ..Default::default()
154 };
155
156 let expected = vec![
157 ("get", &operation),
158 ("post", &operation),
159 ("delete", &operation),
160 ];
161 assert_eq!(path_item.iter().collect::<Vec<_>>(), expected);
162
163 let expected = vec![
164 ("get", operation.clone()),
165 ("post", operation.clone()),
166 ("delete", operation.clone()),
167 ];
168 assert_eq!(path_item.into_iter().collect::<Vec<_>>(), expected);
169 }
170}