1use crate::convert::IntoAttributeValue;
16use crate::error::{Error, Result};
17use crate::namespaces::NSChoice;
18use crate::node::Node;
19use crate::prefixes::{Namespace, Prefix, Prefixes};
20use crate::tree_builder::TreeBuilder;
21
22use alloc::borrow::Cow;
23use alloc::string::String;
24use alloc::vec::Vec;
25
26use core::borrow::Borrow;
27use core::hash::Hash;
28use core::slice;
29use core::str::FromStr;
30
31use std::io;
32
33use rxml::writer::{Encoder, Item, TrackNamespace};
34use rxml::{AttrMap, Namespace as RxmlNamespace, NcName, RawReader, XmlVersion};
35
36fn encode_and_write<W: io::Write, T: rxml::writer::TrackNamespace>(
37 item: Item<'_>,
38 enc: &mut Encoder<T>,
39 mut w: W,
40) -> io::Result<()> {
41 let mut buf = rxml::bytes::BytesMut::new();
42 enc.encode_into_bytes(item, &mut buf)
43 .expect("encoder driven incorrectly");
44 w.write_all(&buf[..])?;
45 Ok(())
46}
47
48pub struct CustomItemWriter<W, T> {
51 writer: W,
52 encoder: Encoder<T>,
53}
54
55impl<W: io::Write> CustomItemWriter<W, rxml::writer::SimpleNamespaces> {
56 pub(crate) fn new(writer: W) -> Self {
57 Self {
58 writer,
59 encoder: Encoder::new(),
60 }
61 }
62}
63
64impl<W: io::Write, T: rxml::writer::TrackNamespace> CustomItemWriter<W, T> {
65 pub(crate) fn write(&mut self, item: Item<'_>) -> io::Result<()> {
66 encode_and_write(item, &mut self.encoder, &mut self.writer)
67 }
68}
69
70pub type ItemWriter<W> = CustomItemWriter<W, rxml::writer::SimpleNamespaces>;
73
74#[must_use]
78pub fn escape(raw: &[u8]) -> Cow<'_, [u8]> {
79 fn to_escape(b: u8) -> bool {
80 matches!(b, b'<' | b'>' | b'\'' | b'&' | b'"')
81 }
82
83 let mut escapes: Vec<(usize, &'static [u8])> = Vec::new();
84 let mut bytes = raw.iter();
85 let mut loc = 0;
86 while let Some(i) = bytes.position(|&b| to_escape(b)) {
87 loc += i;
88 match raw[loc] {
89 b'<' => escapes.push((loc, b"<")),
90 b'>' => escapes.push((loc, b">")),
91 b'\'' => escapes.push((loc, b"'")),
92 b'&' => escapes.push((loc, b"&")),
93 b'"' => escapes.push((loc, b""")),
94 _ => unreachable!("Only '<', '>', '\'', '&' and '\"' are escaped"),
95 }
96 loc += 1;
97 }
98
99 if escapes.is_empty() {
100 Cow::Borrowed(raw)
101 } else {
102 let len = raw.len();
103 let mut v = Vec::with_capacity(len);
104 let mut start = 0;
105 for (i, r) in escapes {
106 v.extend_from_slice(&raw[start..i]);
107 v.extend_from_slice(r);
108 start = i + 1;
109 }
110
111 if start < len {
112 v.extend_from_slice(&raw[start..]);
113 }
114 Cow::Owned(v)
115 }
116}
117
118#[derive(Clone, Eq, Debug)]
119pub struct Element {
121 name: String,
122 namespace: RxmlNamespace<'static>,
123 pub prefixes: Prefixes,
125 attributes: AttrMap,
126 children: Vec<Node>,
127}
128
129impl<'a> From<&'a Element> for String {
130 fn from(elem: &'a Element) -> String {
131 let mut writer = Vec::new();
132 elem.write_to(&mut writer).unwrap();
133 String::from_utf8(writer).unwrap()
134 }
135}
136
137impl FromStr for Element {
138 type Err = Error;
139
140 fn from_str(s: &str) -> Result<Element> {
141 Element::from_reader(s.as_bytes())
142 }
143}
144
145impl PartialEq for Element {
146 fn eq(&self, other: &Self) -> bool {
147 if self.name() == other.name() && self.ns() == other.ns() && self.attrs().eq(other.attrs())
148 {
149 if self.nodes().count() != other.nodes().count() {
150 return false;
151 }
152 self.nodes()
153 .zip(other.nodes())
154 .all(|(node1, node2)| node1 == node2)
155 } else {
156 false
157 }
158 }
159}
160
161impl Element {
162 pub(crate) fn new<P: Into<Prefixes>>(
163 name: String,
164 namespace: String,
165 prefixes: P,
166 attributes: AttrMap,
167 children: Vec<Node>,
168 ) -> Element {
169 Element {
170 name,
171 namespace: namespace.into(),
172 prefixes: prefixes.into(),
173 attributes,
174 children,
175 }
176 }
177
178 pub fn builder<S: AsRef<str>, NS: Into<String>>(name: S, namespace: NS) -> ElementBuilder {
198 ElementBuilder {
199 root: Element::new(
200 name.as_ref().to_string(),
201 namespace.into(),
202 None,
203 AttrMap::new(),
204 Vec::new(),
205 ),
206 }
207 }
208
209 pub fn bare<S: Into<String>, NS: Into<String>>(name: S, namespace: NS) -> Element {
225 Element::new(
226 name.into(),
227 namespace.into(),
228 None,
229 AttrMap::new(),
230 Vec::new(),
231 )
232 }
233
234 #[must_use]
236 pub fn name(&self) -> &str {
237 &self.name
238 }
239
240 #[must_use]
242 pub fn ns(&self) -> String {
243 self.namespace.clone().into()
244 }
245
246 #[must_use]
248 pub fn attr<'a, N: Ord + Hash + Eq + ?Sized>(&'a self, name: &'a N) -> Option<&'a str>
249 where
250 NcName: Borrow<N>,
251 {
252 if let Some(value) = self.attributes.get(&RxmlNamespace::NONE, name) {
253 return Some(value);
254 }
255 None
256 }
257
258 #[must_use]
260 pub fn attr_ns<'a, NS: Ord + Hash + Eq + ?Sized, N: Ord + Hash + Eq + ?Sized>(
261 &'a self,
262 ns: &NS,
263 name: &N,
264 ) -> Option<&'a str>
265 where
266 RxmlNamespace<'static>: Borrow<NS>,
267 NcName: Borrow<N>,
268 {
269 if let Some(value) = self.attributes.get(ns, name) {
270 return Some(value);
271 }
272 None
273 }
274
275 #[must_use]
291 pub fn attrs(&self) -> &AttrMap {
292 &self.attributes
293 }
294
295 #[must_use]
298 pub fn attrs_mut(&mut self) -> &mut AttrMap {
299 &mut self.attributes
300 }
301
302 pub fn set_attr<V: IntoAttributeValue>(
304 &mut self,
305 ns: RxmlNamespace<'static>,
306 name: NcName,
307 val: V,
308 ) {
309 let val = val.into_attribute_value();
310
311 if let Some(value) = self.attributes.get_mut(&ns, &name) {
312 *value = val
313 .expect("removing existing value via set_attr, this is not yet supported (TODO)"); return;
315 }
316
317 if let Some(val) = val {
318 self.attributes.insert(ns.clone(), name, val);
319 }
320 }
321
322 pub fn is<'a, N: AsRef<str>, NS: Into<NSChoice<'a>>>(&self, name: N, namespace: NS) -> bool {
342 self.name == name.as_ref() && namespace.into().compare(self.namespace.as_ref())
343 }
344
345 pub fn has_ns<'a, NS: Into<NSChoice<'a>>>(&self, namespace: NS) -> bool {
363 namespace.into().compare(self.namespace.as_ref())
364 }
365
366 fn from_reader_inner<R: io::BufRead>(
367 mut tree_builder: TreeBuilder,
368 reader: R,
369 ) -> Result<Element> {
370 let mut driver = RawReader::new(reader);
371 while let Some(event) = driver.read()? {
372 tree_builder.process_event(event)?;
373
374 if let Some(root) = tree_builder.root.take() {
375 return Ok(root);
376 }
377 }
378 Err(Error::EndOfDocument)
379 }
380
381 pub fn from_reader<R: io::BufRead>(reader: R) -> Result<Element> {
383 Element::from_reader_inner(TreeBuilder::new(), reader)
384 }
385
386 pub fn from_reader_with_prefixes<R: io::BufRead, P: Into<Prefixes>>(
390 reader: R,
391 prefixes: P,
392 ) -> Result<Element> {
393 let tree_builder = TreeBuilder::new().with_prefixes_stack([prefixes.into()].into());
394 Element::from_reader_inner(tree_builder, reader)
395 }
396
397 pub fn write_to<W: io::Write>(&self, writer: &mut W) -> Result<()> {
399 self.to_writer(&mut ItemWriter::new(writer))
400 }
401
402 pub fn write_to_decl<W: io::Write>(&self, writer: &mut W) -> Result<()> {
404 self.to_writer_decl(&mut ItemWriter::new(writer))
405 }
406
407 pub fn to_writer<W: io::Write>(&self, writer: &mut ItemWriter<W>) -> Result<()> {
409 self.write_to_inner(writer)
410 }
411
412 pub fn to_writer_decl<W: io::Write>(&self, writer: &mut ItemWriter<W>) -> Result<()> {
414 writer
415 .write(Item::XmlDeclaration(XmlVersion::V1_0))
416 .unwrap(); self.write_to_inner(writer)
418 }
419
420 pub fn write_to_inner<W: io::Write>(&self, writer: &mut ItemWriter<W>) -> Result<()> {
422 for (prefix, namespace) in self.prefixes.declared_prefixes() {
423 assert!(writer.encoder.ns_tracker_mut().declare_fixed(
424 prefix.as_deref().map(TryInto::try_into).transpose()?,
425 namespace.clone().into(),
426 ));
427 }
428
429 writer.write(Item::ElementHeadStart(
430 self.namespace.clone(),
431 (*self.name).try_into()?,
432 ))?;
433
434 for ((ns, key), value) in &self.attributes {
435 writer.write(Item::Attribute(ns.clone(), key, value))?;
436 }
437
438 if !self.children.is_empty() {
439 writer.write(Item::ElementHeadEnd)?;
440 for child in &self.children {
441 child.write_to_inner(writer)?;
442 }
443 }
444 writer.write(Item::ElementFoot)?;
445
446 Ok(())
447 }
448
449 pub fn take_nodes(&mut self) -> Vec<Node> {
451 self.children.drain(..).collect()
452 }
453
454 #[inline]
473 pub fn nodes(&self) -> Nodes<'_> {
474 self.children.iter()
475 }
476
477 #[inline]
479 pub fn nodes_mut(&mut self) -> NodesMut<'_> {
480 self.children.iter_mut()
481 }
482
483 #[inline]
499 #[must_use]
500 pub fn children(&self) -> Children<'_> {
501 Children {
502 iter: self.children.iter(),
503 }
504 }
505
506 #[inline]
508 #[must_use]
509 pub fn children_mut(&mut self) -> ChildrenMut<'_> {
510 ChildrenMut {
511 iter: self.children.iter_mut(),
512 }
513 }
514
515 #[inline]
524 #[doc(hidden)]
525 pub fn take_contents_as_children(&mut self) -> ContentsAsChildren<'_> {
526 ContentsAsChildren {
527 iter: self.children.drain(..),
528 }
529 }
530
531 #[inline]
546 #[must_use]
547 pub fn texts(&self) -> Texts<'_> {
548 Texts {
549 iter: self.children.iter(),
550 }
551 }
552
553 #[inline]
555 #[must_use]
556 pub fn texts_mut(&mut self) -> TextsMut<'_> {
557 TextsMut {
558 iter: self.children.iter_mut(),
559 }
560 }
561
562 pub fn append_child(&mut self, child: Element) -> &mut Element {
586 self.children.push(Node::Element(child));
587 if let Node::Element(ref mut cld) = *self.children.last_mut().unwrap() {
588 cld
589 } else {
590 unreachable!()
591 }
592 }
593
594 pub fn append_text_node<S: Into<String>>(&mut self, child: S) {
610 self.children.push(Node::Text(child.into()));
611 }
612
613 pub fn append_text<S: Into<String>>(&mut self, text: S) {
634 if let Some(Node::Text(ref mut child)) = self.children.last_mut() {
635 child.push_str(&text.into());
636 } else {
637 self.append_text_node(text);
638 }
639 }
640
641 pub fn append_node(&mut self, node: Node) {
655 self.children.push(node);
656 }
657
658 #[must_use]
670 pub fn text(&self) -> String {
671 self.texts().fold(String::new(), |ret, new| ret + new)
672 }
673
674 pub fn get_child<'a, N: AsRef<str>, NS: Into<NSChoice<'a>>>(
691 &self,
692 name: N,
693 namespace: NS,
694 ) -> Option<&Element> {
695 let namespace = namespace.into();
696 for fork in &self.children {
697 if let Node::Element(ref e) = *fork {
698 if e.is(name.as_ref(), namespace) {
699 return Some(e);
700 }
701 }
702 }
703 None
704 }
705
706 pub fn get_child_mut<'a, N: AsRef<str>, NS: Into<NSChoice<'a>>>(
709 &mut self,
710 name: N,
711 namespace: NS,
712 ) -> Option<&mut Element> {
713 let namespace = namespace.into();
714 for fork in &mut self.children {
715 if let Node::Element(ref mut e) = *fork {
716 if e.is(name.as_ref(), namespace) {
717 return Some(e);
718 }
719 }
720 }
721 None
722 }
723
724 pub fn has_child<'a, N: AsRef<str>, NS: Into<NSChoice<'a>>>(
741 &self,
742 name: N,
743 namespace: NS,
744 ) -> bool {
745 self.get_child(name, namespace).is_some()
746 }
747
748 pub fn remove_child<'a, N: AsRef<str>, NS: Into<NSChoice<'a>>>(
763 &mut self,
764 name: N,
765 namespace: NS,
766 ) -> Option<Element> {
767 let name = name.as_ref();
768 let namespace = namespace.into();
769 let idx = self.children.iter().position(|x| {
770 if let Node::Element(ref elm) = x {
771 elm.is(name, namespace)
772 } else {
773 false
774 }
775 })?;
776 self.children.remove(idx).into_element()
777 }
778
779 pub fn unshift_child(&mut self) -> Option<Element> {
782 while !self.children.is_empty() {
783 if let Some(el) = self.children.remove(0).into_element() {
784 return Some(el);
785 }
786 }
787
788 None
789 }
790}
791
792pub struct Children<'a> {
794 iter: slice::Iter<'a, Node>,
795}
796
797impl<'a> Iterator for Children<'a> {
798 type Item = &'a Element;
799
800 fn next(&mut self) -> Option<&'a Element> {
801 for item in &mut self.iter {
802 if let Node::Element(ref child) = *item {
803 return Some(child);
804 }
805 }
806 None
807 }
808}
809
810pub struct ChildrenMut<'a> {
812 iter: slice::IterMut<'a, Node>,
813}
814
815impl<'a> Iterator for ChildrenMut<'a> {
816 type Item = &'a mut Element;
817
818 fn next(&mut self) -> Option<&'a mut Element> {
819 for item in &mut self.iter {
820 if let Node::Element(ref mut child) = *item {
821 return Some(child);
822 }
823 }
824 None
825 }
826}
827
828pub struct ContentsAsChildren<'a> {
830 iter: alloc::vec::Drain<'a, Node>,
831}
832
833impl Iterator for ContentsAsChildren<'_> {
834 type Item = Element;
835
836 fn next(&mut self) -> Option<Element> {
837 for item in &mut self.iter {
838 if let Node::Element(child) = item {
839 return Some(child);
840 }
841 }
842 None
843 }
844}
845
846pub struct Texts<'a> {
848 iter: slice::Iter<'a, Node>,
849}
850
851impl<'a> Iterator for Texts<'a> {
852 type Item = &'a str;
853
854 fn next(&mut self) -> Option<&'a str> {
855 for item in &mut self.iter {
856 if let Node::Text(ref child) = *item {
857 return Some(child);
858 }
859 }
860 None
861 }
862}
863
864pub struct TextsMut<'a> {
866 iter: slice::IterMut<'a, Node>,
867}
868
869impl<'a> Iterator for TextsMut<'a> {
870 type Item = &'a mut String;
871
872 fn next(&mut self) -> Option<&'a mut String> {
873 for item in &mut self.iter {
874 if let Node::Text(ref mut child) = *item {
875 return Some(child);
876 }
877 }
878 None
879 }
880}
881
882pub type Nodes<'a> = slice::Iter<'a, Node>;
884
885pub type NodesMut<'a> = slice::IterMut<'a, Node>;
887
888pub struct ElementBuilder {
890 root: Element,
891}
892
893impl ElementBuilder {
894 pub fn prefix<S: Into<Namespace>>(
896 mut self,
897 prefix: Prefix,
898 namespace: S,
899 ) -> Result<ElementBuilder> {
900 if self.root.prefixes.get(&prefix).is_some() {
901 return Err(Error::DuplicatePrefix);
902 }
903 self.root.prefixes.insert(prefix, namespace.into());
904 Ok(self)
905 }
906
907 #[must_use]
909 pub fn attr<V: IntoAttributeValue>(mut self, name: NcName, value: V) -> ElementBuilder {
910 self.root.set_attr(RxmlNamespace::NONE, name, value);
911 self
912 }
913
914 #[must_use]
916 pub fn attr_ns<V: IntoAttributeValue>(
917 mut self,
918 ns: RxmlNamespace<'static>,
919 name: NcName,
920 value: V,
921 ) -> ElementBuilder {
922 self.root.set_attr(ns, name, value);
923 self
924 }
925
926 #[must_use]
928 pub fn append<T: Into<Node>>(mut self, node: T) -> ElementBuilder {
929 self.root.append_node(node.into());
930 self
931 }
932
933 #[must_use]
935 pub fn append_all<T: Into<Node>, I: IntoIterator<Item = T>>(
936 mut self,
937 iter: I,
938 ) -> ElementBuilder {
939 for node in iter {
940 self.root.append_node(node.into());
941 }
942 self
943 }
944
945 #[must_use]
947 pub fn build(self) -> Element {
948 self.root
949 }
950}
951
952#[cfg(test)]
953mod tests {
954 use super::*;
955 use rxml::xml_ncname;
956 use std::collections::BTreeMap;
957
958 #[test]
959 fn test_element_new() {
960 let mut attrs = AttrMap::new();
961 attrs.insert(
962 String::from("namespace").into(),
963 xml_ncname!("name").to_owned(),
964 "value".to_string(),
965 );
966 let elem = Element::new(
967 "name".to_owned(),
968 "namespace".to_owned(),
969 (None, "namespace".to_owned()),
970 attrs,
971 Vec::new(),
972 );
973
974 assert_eq!(elem.name(), "name");
975 assert_eq!(elem.ns(), "namespace".to_owned());
976 assert_eq!(elem.attr_ns("namespace", "name"), Some("value"));
977 assert_eq!(elem.attr("inexistent"), None);
978 }
979
980 #[test]
981 fn test_from_reader_simple() {
982 let xml = b"<foo xmlns='ns1'></foo>";
983 let elem = Element::from_reader(&xml[..]);
984
985 let elem2 = Element::builder("foo", "ns1").build();
986
987 assert_eq!(elem.unwrap(), elem2);
988 }
989
990 #[test]
991 fn test_from_reader_nested() {
992 let xml = b"<foo xmlns='ns1'><bar xmlns='ns1' baz='qxx' /></foo>";
993 let elem = Element::from_reader(&xml[..]);
994
995 let nested = Element::builder("bar", "ns1")
996 .attr(xml_ncname!("baz").to_owned(), "qxx")
997 .build();
998 let elem2 = Element::builder("foo", "ns1").append(nested).build();
999
1000 assert_eq!(elem.unwrap(), elem2);
1001 }
1002
1003 #[test]
1004 fn test_from_reader_with_prefix() {
1005 let xml = b"<foo xmlns='ns1'><prefix:bar xmlns:prefix='ns1' baz='qxx' /></foo>";
1006 let elem = Element::from_reader(&xml[..]);
1007
1008 let nested = Element::builder("bar", "ns1")
1009 .attr(xml_ncname!("baz").to_owned(), "qxx")
1010 .build();
1011 let elem2 = Element::builder("foo", "ns1").append(nested).build();
1012
1013 assert_eq!(elem.unwrap(), elem2);
1014 }
1015
1016 #[test]
1017 fn test_from_reader_split_prefix() {
1018 let xml = b"<foo:bar xmlns:foo='ns1'/>";
1019 let elem = Element::from_reader(&xml[..]).unwrap();
1020
1021 assert_eq!(elem.name(), String::from("bar"));
1022 assert_eq!(elem.ns(), String::from("ns1"));
1023 assert_eq!(
1025 elem.prefixes.get(&Some(String::from("foo"))),
1026 Some(&String::from("ns1"))
1027 );
1028 }
1029
1030 #[test]
1031 fn parses_spectest_xml() {
1032 let xml = br#"<rng:grammar xmlns:rng="http://relaxng.org/ns/structure/1.0">
1034 <rng:name xmlns:rng="http://relaxng.org/ns/structure/1.0"></rng:name>
1035 </rng:grammar>
1036 "#;
1037 let _ = Element::from_reader(&xml[..]).unwrap();
1038 }
1039
1040 #[test]
1041 fn does_not_unescape_cdata() {
1042 let xml = b"<test xmlns='test'><![CDATA['>blah<blah>]]></test>";
1043 let elem = Element::from_reader(&xml[..]).unwrap();
1044 assert_eq!(elem.text(), "'>blah<blah>");
1045 }
1046
1047 #[test]
1048 fn test_compare_all_ns() {
1049 let xml = b"<foo xmlns='foo' xmlns:bar='baz'><bar:meh xmlns:bar='baz' /></foo>";
1050 let elem = Element::from_reader(&xml[..]).unwrap();
1051
1052 let elem2 = elem.clone();
1053
1054 let xml3 = b"<foo xmlns='foo'><bar:meh xmlns:bar='baz'/></foo>";
1055 let elem3 = Element::from_reader(&xml3[..]).unwrap();
1056
1057 let xml4 = b"<prefix:foo xmlns:prefix='foo'><bar:meh xmlns:bar='baz'/></prefix:foo>";
1058 let elem4 = Element::from_reader(&xml4[..]).unwrap();
1059
1060 assert_eq!(elem, elem2);
1061 assert_eq!(elem, elem3);
1062 assert_eq!(elem, elem4);
1063 }
1064
1065 #[test]
1066 fn test_compare_empty_children() {
1067 let elem1 = Element::bare("p", "");
1068 let elem2 = Element::builder("p", "")
1069 .append(Node::Element(Element::bare("span", "")))
1070 .build();
1071
1072 assert_ne!(elem1, elem2);
1073 }
1074
1075 #[test]
1076 fn test_from_reader_with_prefixes() {
1077 let xml = b"<foo><bar xmlns='baz'/></foo>";
1078 let elem =
1079 Element::from_reader_with_prefixes(&xml[..], String::from("jabber:client")).unwrap();
1080
1081 let xml2 = b"<foo xmlns='jabber:client'><bar xmlns='baz'/></foo>";
1082 let elem2 = Element::from_reader(&xml2[..]).unwrap();
1083
1084 assert_eq!(elem, elem2);
1085 }
1086
1087 #[test]
1088 fn test_from_reader_with_prefixes_serialization() {
1089 let prefixes: BTreeMap<Option<String>, String> = {
1090 let mut tmp = BTreeMap::new();
1091 tmp.insert(None, String::from("foo"));
1092 tmp.insert(Some(String::from("test")), String::from("bar"));
1093 tmp
1094 };
1095
1096 let input = r#"<foo test:attr="true"><bar/></foo>"#;
1097 let output = r#"<foo xmlns='foo' xmlns:test='bar' test:attr='true'><bar/></foo>"#;
1098
1099 let elem = Element::from_reader_with_prefixes(input.as_ref(), prefixes).unwrap();
1100 assert_eq!(String::from(&elem), output);
1101 }
1102
1103 #[test]
1104 fn failure_with_duplicate_namespace() {
1105 let _: Element = r###"<?xml version="1.0" encoding="UTF-8"?>
1106 <wsdl:definitions
1107 xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
1108 xmlns:xsd="http://www.w3.org/2001/XMLSchema">
1109 <wsdl:types>
1110 <xsd:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
1111 </xsd:schema>
1112 </wsdl:types>
1113 </wsdl:definitions>
1114 "###
1115 .parse()
1116 .unwrap();
1117 }
1118}