elementtree/xml/
attribute.rs

1//! Contains XML attributes manipulation types and functions.
2//!
3
4use std::fmt;
5
6use crate::xml::escape::escape_str_attribute;
7use crate::xml::name::{Name, OwnedName};
8
9/// A borrowed version of an XML attribute.
10///
11/// Consists of a borrowed qualified name and a borrowed string value.
12#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
13pub struct Attribute<'a> {
14    /// Attribute name.
15    pub name: Name<'a>,
16
17    /// Attribute value.
18    pub value: &'a str,
19}
20
21impl<'a> fmt::Display for Attribute<'a> {
22    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
23        write!(f, "{}=\"{}\"", self.name, escape_str_attribute(self.value))
24    }
25}
26
27impl<'a> Attribute<'a> {
28    /// Creates a borrowed attribute using the provided borrowed name and a borrowed string value.
29    #[inline]
30    #[cfg(test)]
31    pub fn new(name: Name<'a>, value: &'a str) -> Attribute<'a> {
32        Attribute { name, value }
33    }
34}
35
36/// An owned version of an XML attribute.
37///
38/// Consists of an owned qualified name and an owned string value.
39#[derive(Clone, Eq, PartialEq, Hash, Debug)]
40pub struct OwnedAttribute {
41    /// Attribute name.
42    pub name: OwnedName,
43
44    /// Attribute value.
45    pub value: String,
46}
47
48impl OwnedAttribute {
49    /// Returns a borrowed `Attribute` out of this owned one.
50    #[cfg(test)]
51    pub fn borrow(&self) -> Attribute<'_> {
52        Attribute {
53            name: self.name.borrow(),
54            value: &*self.value,
55        }
56    }
57
58    /// Creates a new owned attribute using the provided owned name and an owned string value.
59    #[inline]
60    #[cfg(test)]
61    pub fn new<S: Into<String>>(name: OwnedName, value: S) -> OwnedAttribute {
62        OwnedAttribute {
63            name,
64            value: value.into(),
65        }
66    }
67}
68
69impl fmt::Display for OwnedAttribute {
70    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
71        write!(
72            f,
73            "{}=\"{}\"",
74            self.name,
75            escape_str_attribute(&*self.value)
76        )
77    }
78}
79
80#[cfg(test)]
81mod tests {
82    use super::Attribute;
83
84    use crate::xml::name::Name;
85
86    #[test]
87    fn attribute_display() {
88        let attr = Attribute::new(
89            Name::qualified("attribute", "urn:namespace", Some("n")),
90            "its value with > & \" ' < weird symbols",
91        );
92
93        assert_eq!(
94            &*attr.to_string(),
95            "{urn:namespace}n:attribute=\"its value with &gt; &amp; &quot; &apos; &lt; weird symbols\""
96        )
97    }
98}