salvo_oapi/openapi/
xml.rs

1//! Implements [OpenAPI Xml Object][xml_object] types.
2//!
3//! [xml_object]: https://spec.openapis.org/oas/latest.html#xml-object
4use std::borrow::Cow;
5
6use serde::{Deserialize, Serialize};
7
8/// Implements [OpenAPI Xml Object][xml_object].
9///
10/// Can be used to modify xml output format of specific [OpenAPI Schema Object][schema_object] which are
11/// implemented in [`schema`][schema] module.
12///
13/// [xml_object]: https://spec.openapis.org/oas/latest.html#xml-object
14/// [schema_object]: https://spec.openapis.org/oas/latest.html#schema-object
15/// [schema]: ../schema/index.html
16#[non_exhaustive]
17#[derive(Serialize, Deserialize, Default, Clone, Debug, PartialEq, Eq)]
18pub struct Xml {
19    /// Used to replace the name of attribute or type used in schema property.
20    /// When used with [`Xml::wrapped`] attribute the name will be used as a wrapper name
21    /// for wrapped array instead of the item or type name.
22    #[serde(skip_serializing_if = "Option::is_none")]
23    pub name: Option<Cow<'static, str>>,
24
25    /// Valid uri definition of namespace used in xml.
26    #[serde(skip_serializing_if = "Option::is_none")]
27    pub namespace: Option<Cow<'static, str>>,
28
29    /// Prefix for xml element [`Xml::name`].
30    #[serde(skip_serializing_if = "Option::is_none")]
31    pub prefix: Option<Cow<'static, str>>,
32
33    /// Flag deciding will this attribute translate to element attribute instead of xml element.
34    #[serde(skip_serializing_if = "Option::is_none")]
35    pub attribute: Option<bool>,
36
37    /// Flag only usable with array definition. If set to true the output xml will wrap the array of items
38    /// `<pets><pet></pet></pets>` instead of unwrapped `<pet></pet>`.
39    #[serde(skip_serializing_if = "Option::is_none")]
40    pub wrapped: Option<bool>,
41}
42
43impl Xml {
44    /// Construct a new [`Xml`] object.
45    pub fn new() -> Self {
46        Self {
47            ..Default::default()
48        }
49    }
50}
51
52impl Xml {
53    /// Add [`Xml::name`] to xml object.
54    ///
55    /// Builder style chainable consuming add name method.
56    pub fn name<S: Into<Cow<'static, str>>>(mut self, name: S) -> Self {
57        self.name = Some(name.into());
58        self
59    }
60
61    /// Add [`Xml::namespace`] to xml object.
62    ///
63    /// Builder style chainable consuming add namespace method.
64    pub fn namespace<S: Into<Cow<'static, str>>>(mut self, namespace: S) -> Self {
65        self.namespace = Some(namespace.into());
66        self
67    }
68
69    /// Add [`Xml::prefix`] to xml object.
70    ///
71    /// Builder style chainable consuming add prefix method.
72    pub fn prefix<S: Into<Cow<'static, str>>>(mut self, prefix: S) -> Self {
73        self.prefix = Some(prefix.into());
74        self
75    }
76
77    /// Mark [`Xml`] object as attribute. See [`Xml::attribute`]
78    ///
79    /// Builder style chainable consuming add attribute method.
80    pub fn attribute(mut self, attribute: bool) -> Self {
81        self.attribute = Some(attribute);
82        self
83    }
84
85    /// Mark [`Xml`] object wrapped. See [`Xml::wrapped`]
86    ///
87    /// Builder style chainable consuming add wrapped method.
88    pub fn wrapped(mut self, wrapped: bool) -> Self {
89        self.wrapped = Some(wrapped);
90        self
91    }
92}
93
94#[cfg(test)]
95mod tests {
96    use super::Xml;
97
98    #[test]
99    fn xml_new() {
100        let mut xml = Xml::new();
101
102        assert!(xml.name.is_none());
103        assert!(xml.namespace.is_none());
104        assert!(xml.prefix.is_none());
105        assert!(xml.attribute.is_none());
106        assert!(xml.wrapped.is_none());
107
108        xml = xml.name("name");
109        assert!(xml.name.is_some());
110
111        xml = xml.namespace("namespave");
112        assert!(xml.namespace.is_some());
113
114        xml = xml.prefix("prefix");
115        assert!(xml.prefix.is_some());
116
117        xml = xml.attribute(true);
118        assert!(xml.attribute.is_some());
119
120        xml = xml.wrapped(true);
121        assert!(xml.wrapped.is_some());
122    }
123}