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")]
24 pub get: Option<Operation>,
25 #[serde(skip_serializing_if = "Option::is_none")]
27 pub put: Option<Operation>,
28 #[serde(skip_serializing_if = "Option::is_none")]
30 pub post: Option<Operation>,
31 #[serde(skip_serializing_if = "Option::is_none")]
33 pub delete: Option<Operation>,
34 #[serde(skip_serializing_if = "Option::is_none")]
36 pub options: Option<Operation>,
37 #[serde(skip_serializing_if = "Option::is_none")]
39 pub head: Option<Operation>,
40 #[serde(skip_serializing_if = "Option::is_none")]
42 pub patch: Option<Operation>,
43 #[serde(skip_serializing_if = "Option::is_none")]
45 pub trace: Option<Operation>,
46 #[serde(default, skip_serializing_if = "Vec::is_empty")]
48 pub servers: Vec<Server>,
49 #[serde(default, skip_serializing_if = "Vec::is_empty")]
57 pub parameters: Vec<ReferenceOr<Parameter>>,
58 #[serde(flatten, deserialize_with = "crate::util::deserialize_extensions")]
60 pub extensions: IndexMap<String, serde_json::Value>,
61}
62
63impl PathItem {
64 pub fn iter(&self) -> impl Iterator<Item = (&str, &'_ Operation)> {
66 vec![
67 ("get", &self.get),
68 ("put", &self.put),
69 ("post", &self.post),
70 ("delete", &self.delete),
71 ("options", &self.options),
72 ("head", &self.head),
73 ("patch", &self.patch),
74 ("trace", &self.trace),
75 ]
76 .into_iter()
77 .filter_map(|(method, maybe_op)| maybe_op.as_ref().map(|op| (method, op)))
78 }
79}
80
81impl IntoIterator for PathItem {
82 type Item = (&'static str, Operation);
83
84 type IntoIter = std::vec::IntoIter<Self::Item>;
85
86 fn into_iter(self) -> Self::IntoIter {
88 vec![
89 ("get", self.get),
90 ("put", self.put),
91 ("post", self.post),
92 ("delete", self.delete),
93 ("options", self.options),
94 ("head", self.head),
95 ("patch", self.patch),
96 ("trace", self.trace),
97 ]
98 .into_iter()
99 .filter_map(|(method, maybe_op)| maybe_op.map(|op| (method, op)))
100 .collect::<Vec<_>>()
101 .into_iter()
102 }
103}
104
105#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
110pub struct Paths {
111 #[serde(flatten, deserialize_with = "deserialize_paths")]
113 pub paths: IndexMap<String, ReferenceOr<PathItem>>,
114 #[serde(flatten, deserialize_with = "crate::util::deserialize_extensions")]
116 pub extensions: IndexMap<String, serde_json::Value>,
117}
118
119impl Paths {
120 pub fn iter(&self) -> indexmap::map::Iter<String, ReferenceOr<PathItem>> {
122 self.paths.iter()
123 }
124}
125
126impl IntoIterator for Paths {
127 type Item = (String, ReferenceOr<PathItem>);
128
129 type IntoIter = indexmap::map::IntoIter<String, ReferenceOr<PathItem>>;
130
131 fn into_iter(self) -> Self::IntoIter {
132 self.paths.into_iter()
133 }
134}
135
136fn deserialize_paths<'de, D>(
137 deserializer: D,
138) -> Result<IndexMap<String, ReferenceOr<PathItem>>, D::Error>
139where
140 D: Deserializer<'de>,
141{
142 deserializer.deserialize_map(PredicateVisitor(
143 |key: &String| key.starts_with('/'),
144 PhantomData,
145 ))
146}
147
148#[cfg(test)]
149mod tests {
150 use super::*;
151
152 #[test]
153 fn test_path_item_iterators() {
154 let operation = Operation::default();
155
156 let path_item = PathItem {
157 get: Some(operation.clone()),
158 post: Some(operation.clone()),
159 delete: Some(operation.clone()),
160 ..Default::default()
161 };
162
163 let expected = vec![
164 ("get", &operation),
165 ("post", &operation),
166 ("delete", &operation),
167 ];
168 assert_eq!(path_item.iter().collect::<Vec<_>>(), expected);
169
170 let expected = vec![
171 ("get", operation.clone()),
172 ("post", operation.clone()),
173 ("delete", operation.clone()),
174 ];
175 assert_eq!(path_item.into_iter().collect::<Vec<_>>(), expected);
176 }
177}