xml_no_std/
attribute.rs

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