kynos_openapi/model/paths/
mod.rs1pub mod item;
4pub mod method;
5pub mod operation;
6pub mod template;
7
8use std::fmt;
9
10use serde::{
11 Deserialize, Deserializer, Serialize, Serializer,
12 de::{MapAccess, Visitor},
13 ser::SerializeMap,
14};
15
16use crate::{
17 Map,
18 model::{
19 extensions::Extensions,
20 paths::{item::PathItem, template::PathTemplate},
21 },
22};
23
24#[derive(Clone, Debug, Default, PartialEq)]
32pub struct Paths {
33 pub items: Map<PathItem>,
35
36 pub extensions: Extensions,
38}
39
40impl Paths {
41 #[must_use]
43 pub fn new() -> Self {
44 Self::default()
45 }
46
47 pub fn insert(&mut self, template: &PathTemplate, item: PathItem) -> Option<PathItem> {
49 self.items.insert(template.as_str().to_owned(), item)
50 }
51
52 #[must_use]
54 pub fn get(&self, template: &PathTemplate) -> Option<&PathItem> {
55 self.items.get(template.as_str())
56 }
57
58 #[must_use]
64 pub fn is_empty(&self) -> bool {
65 self.items.is_empty() && self.extensions.is_empty()
66 }
67
68 #[must_use]
70 pub fn declares_a_path(&self) -> bool {
71 !self.items.is_empty()
72 }
73}
74
75impl Serialize for Paths {
76 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
77 let mut map = serializer.serialize_map(Some(self.items.len() + self.extensions.0.len()))?;
78 for (key, item) in &self.items {
79 map.serialize_entry(key, item)?;
80 }
81 for (key, value) in &self.extensions.0 {
82 map.serialize_entry(key, value)?;
83 }
84 map.end()
85 }
86}
87
88impl<'de> Deserialize<'de> for Paths {
89 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
90 struct PathsVisitor;
91
92 impl<'de> Visitor<'de> for PathsVisitor {
93 type Value = Paths;
94
95 fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
96 f.write_str("a map of path templates to path items")
97 }
98
99 fn visit_map<A: MapAccess<'de>>(self, mut access: A) -> Result<Paths, A::Error> {
100 let mut paths = Paths::new();
101 while let Some(key) = access.next_key::<String>()? {
102 if key.starts_with(crate::model::extensions::EXTENSION_PREFIX) {
103 paths.extensions.0.insert(key, access.next_value()?);
104 } else {
105 paths.items.insert(key, access.next_value()?);
106 }
107 }
108 Ok(paths)
109 }
110 }
111
112 deserializer.deserialize_map(PathsVisitor)
113 }
114}
115
116#[cfg(test)]
117mod tests;