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