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::{
23 borrow::Cow,
24 collections::btree_map::{self, BTreeMap},
25};
26
27use core::slice;
28use core::str::FromStr;
29
30use std::io;
31
32use rxml::writer::{Encoder, Item, TrackNamespace};
33use rxml::{Namespace as RxmlNamespace, RawReader, XmlVersion};
34
35fn encode_and_write<W: io::Write, T: rxml::writer::TrackNamespace>(
36 item: Item<'_>,
37 enc: &mut Encoder<T>,
38 mut w: W,
39) -> io::Result<()> {
40 let mut buf = rxml::bytes::BytesMut::new();
41 enc.encode_into_bytes(item, &mut buf)
42 .expect("encoder driven incorrectly");
43 w.write_all(&buf[..])?;
44 Ok(())
45}
46
47pub struct CustomItemWriter<W, T> {
50 writer: W,
51 encoder: Encoder<T>,
52}
53
54impl<W: io::Write> CustomItemWriter<W, rxml::writer::SimpleNamespaces> {
55 pub(crate) fn new(writer: W) -> Self {
56 Self {
57 writer,
58 encoder: Encoder::new(),
59 }
60 }
61}
62
63impl<W: io::Write, T: rxml::writer::TrackNamespace> CustomItemWriter<W, T> {
64 pub(crate) fn write(&mut self, item: Item<'_>) -> io::Result<()> {
65 encode_and_write(item, &mut self.encoder, &mut self.writer)
66 }
67}
68
69pub type ItemWriter<W> = CustomItemWriter<W, rxml::writer::SimpleNamespaces>;
72
73pub fn escape(raw: &[u8]) -> Cow<[u8]> {
77 let mut escapes: Vec<(usize, &'static [u8])> = Vec::new();
78 let mut bytes = raw.iter();
79 fn to_escape(b: u8) -> bool {
80 matches!(b, b'<' | b'>' | b'\'' | b'&' | b'"')
81 }
82
83 let mut loc = 0;
84 while let Some(i) = bytes.position(|&b| to_escape(b)) {
85 loc += i;
86 match raw[loc] {
87 b'<' => escapes.push((loc, b"<")),
88 b'>' => escapes.push((loc, b">")),
89 b'\'' => escapes.push((loc, b"'")),
90 b'&' => escapes.push((loc, b"&")),
91 b'"' => escapes.push((loc, b""")),
92 _ => unreachable!("Only '<', '>','\', '&' and '\"' are escaped"),
93 }
94 loc += 1;
95 }
96
97 if escapes.is_empty() {
98 Cow::Borrowed(raw)
99 } else {
100 let len = raw.len();
101 let mut v = Vec::with_capacity(len);
102 let mut start = 0;
103 for (i, r) in escapes {
104 v.extend_from_slice(&raw[start..i]);
105 v.extend_from_slice(r);
106 start = i + 1;
107 }
108
109 if start < len {
110 v.extend_from_slice(&raw[start..]);
111 }
112 Cow::Owned(v)
113 }
114}
115
116#[derive(Clone, Eq, Debug)]
117pub struct Element {
119 name: String,
120 namespace: String,
121 pub prefixes: Prefixes,
123 attributes: BTreeMap<String, String>,
124 children: Vec<Node>,
125}
126
127impl<'a> From<&'a Element> for String {
128 fn from(elem: &'a Element) -> String {
129 let mut writer = Vec::new();
130 elem.write_to(&mut writer).unwrap();
131 String::from_utf8(writer).unwrap()
132 }
133}
134
135impl FromStr for Element {
136 type Err = Error;
137
138 fn from_str(s: &str) -> Result<Element> {
139 Element::from_reader(s.as_bytes())
140 }
141}
142
143impl PartialEq for Element {
144 fn eq(&self, other: &Self) -> bool {
145 if self.name() == other.name() && self.ns() == other.ns() && self.attrs().eq(other.attrs())
146 {
147 if self.nodes().count() != other.nodes().count() {
148 return false;
149 }
150 self.nodes()
151 .zip(other.nodes())
152 .all(|(node1, node2)| node1 == node2)
153 } else {
154 false
155 }
156 }
157}
158
159impl Element {
160 pub(crate) fn new<P: Into<Prefixes>>(
161 name: String,
162 namespace: String,
163 prefixes: P,
164 attributes: BTreeMap<String, String>,
165 children: Vec<Node>,
166 ) -> Element {
167 Element {
168 name,
169 namespace,
170 prefixes: prefixes.into(),
171 attributes,
172 children,
173 }
174 }
175
176 pub fn builder<S: AsRef<str>, NS: Into<String>>(name: S, namespace: NS) -> ElementBuilder {
195 ElementBuilder {
196 root: Element::new(
197 name.as_ref().to_string(),
198 namespace.into(),
199 None,
200 BTreeMap::new(),
201 Vec::new(),
202 ),
203 }
204 }
205
206 pub fn bare<S: Into<String>, NS: Into<String>>(name: S, namespace: NS) -> Element {
221 Element::new(
222 name.into(),
223 namespace.into(),
224 None,
225 BTreeMap::new(),
226 Vec::new(),
227 )
228 }
229
230 pub fn name(&self) -> &str {
232 &self.name
233 }
234
235 pub fn ns(&self) -> String {
237 self.namespace.clone()
238 }
239
240 pub fn attr(&self, name: &str) -> Option<&str> {
242 if let Some(value) = self.attributes.get(name) {
243 return Some(value);
244 }
245 None
246 }
247
248 pub fn attrs(&self) -> Attrs {
263 Attrs {
264 iter: self.attributes.iter(),
265 }
266 }
267
268 pub fn attrs_mut(&mut self) -> AttrsMut {
271 AttrsMut {
272 iter: self.attributes.iter_mut(),
273 }
274 }
275
276 pub fn set_attr<S: Into<String>, V: IntoAttributeValue>(&mut self, name: S, val: V) {
278 let name = name.into();
279 let val = val.into_attribute_value();
280
281 if let Some(value) = self.attributes.get_mut(&name) {
282 *value = val
283 .expect("removing existing value via set_attr, this is not yet supported (TODO)"); return;
285 }
286
287 if let Some(val) = val {
288 self.attributes.insert(name, val);
289 }
290 }
291
292 pub fn is<'a, N: AsRef<str>, NS: Into<NSChoice<'a>>>(&self, name: N, namespace: NS) -> bool {
312 self.name == name.as_ref() && namespace.into().compare(self.namespace.as_ref())
313 }
314
315 pub fn has_ns<'a, NS: Into<NSChoice<'a>>>(&self, namespace: NS) -> bool {
333 namespace.into().compare(self.namespace.as_ref())
334 }
335
336 pub fn from_reader<R: io::BufRead>(reader: R) -> Result<Element> {
338 let mut tree_builder = TreeBuilder::new();
339 let mut driver = RawReader::new(reader);
340 while let Some(event) = driver.read()? {
341 tree_builder.process_event(event)?;
342
343 if let Some(root) = tree_builder.root.take() {
344 return Ok(root);
345 }
346 }
347 Err(Error::EndOfDocument)
348 }
349
350 pub fn from_reader_with_prefixes<R: io::BufRead, P: Into<Prefixes>>(
354 reader: R,
355 prefixes: P,
356 ) -> Result<Element> {
357 let mut tree_builder = TreeBuilder::new().with_prefixes_stack(vec![prefixes.into()]);
358 let mut driver = RawReader::new(reader);
359 while let Some(event) = driver.read()? {
360 tree_builder.process_event(event)?;
361
362 if let Some(root) = tree_builder.root.take() {
363 return Ok(root);
364 }
365 }
366 Err(Error::EndOfDocument)
367 }
368
369 pub fn write_to<W: io::Write>(&self, writer: &mut W) -> Result<()> {
371 self.to_writer(&mut ItemWriter::new(writer))
372 }
373
374 pub fn write_to_decl<W: io::Write>(&self, writer: &mut W) -> Result<()> {
376 self.to_writer_decl(&mut ItemWriter::new(writer))
377 }
378
379 pub fn to_writer<W: io::Write>(&self, writer: &mut ItemWriter<W>) -> Result<()> {
381 self.write_to_inner(writer)
382 }
383
384 pub fn to_writer_decl<W: io::Write>(&self, writer: &mut ItemWriter<W>) -> Result<()> {
386 writer
387 .write(Item::XmlDeclaration(XmlVersion::V1_0))
388 .unwrap(); self.write_to_inner(writer)
390 }
391
392 pub fn write_to_inner<W: io::Write>(&self, writer: &mut ItemWriter<W>) -> Result<()> {
394 for (prefix, namespace) in self.prefixes.declared_prefixes() {
395 assert!(writer.encoder.ns_tracker_mut().declare_fixed(
396 prefix.as_ref().map(|x| (&**x).try_into()).transpose()?,
397 namespace.clone().into(),
398 ));
399 }
400
401 let namespace: RxmlNamespace = self.namespace.clone().into();
402 writer.write(Item::ElementHeadStart(&namespace, (*self.name).try_into()?))?;
403
404 for (key, value) in self.attributes.iter() {
405 let (prefix, name) = <&rxml::NameStr>::try_from(&**key)
406 .unwrap()
407 .split_name()
408 .unwrap();
409 let namespace = match prefix {
410 Some(prefix) => match writer.encoder.ns_tracker().lookup_prefix(Some(prefix)) {
411 Ok(v) => v,
412 Err(rxml::writer::PrefixError::Undeclared) => return Err(Error::InvalidPrefix),
413 },
414 None => RxmlNamespace::NONE,
415 };
416 writer.write(Item::Attribute(&namespace, name, value))?;
417 }
418
419 if !self.children.is_empty() {
420 writer.write(Item::ElementHeadEnd)?;
421 for child in self.children.iter() {
422 child.write_to_inner(writer)?;
423 }
424 }
425 writer.write(Item::ElementFoot)?;
426
427 Ok(())
428 }
429
430 pub fn take_nodes(&mut self) -> Vec<Node> {
432 self.children.drain(..).collect()
433 }
434
435 #[inline]
454 pub fn nodes(&self) -> Nodes {
455 self.children.iter()
456 }
457
458 #[inline]
460 pub fn nodes_mut(&mut self) -> NodesMut {
461 self.children.iter_mut()
462 }
463
464 #[inline]
480 pub fn children(&self) -> Children {
481 Children {
482 iter: self.children.iter(),
483 }
484 }
485
486 #[inline]
488 pub fn children_mut(&mut self) -> ChildrenMut {
489 ChildrenMut {
490 iter: self.children.iter_mut(),
491 }
492 }
493
494 #[inline]
503 #[doc(hidden)]
504 pub fn take_contents_as_children(&mut self) -> ContentsAsChildren {
505 ContentsAsChildren {
506 iter: self.children.drain(..),
507 }
508 }
509
510 #[inline]
525 pub fn texts(&self) -> Texts {
526 Texts {
527 iter: self.children.iter(),
528 }
529 }
530
531 #[inline]
533 pub fn texts_mut(&mut self) -> TextsMut {
534 TextsMut {
535 iter: self.children.iter_mut(),
536 }
537 }
538
539 pub fn append_child(&mut self, child: Element) -> &mut Element {
563 self.children.push(Node::Element(child));
564 if let Node::Element(ref mut cld) = *self.children.last_mut().unwrap() {
565 cld
566 } else {
567 unreachable!()
568 }
569 }
570
571 pub fn append_text_node<S: Into<String>>(&mut self, child: S) {
587 self.children.push(Node::Text(child.into()));
588 }
589
590 pub fn append_text<S: Into<String>>(&mut self, text: S) {
611 if let Some(Node::Text(ref mut child)) = self.children.last_mut() {
612 child.push_str(&text.into());
613 } else {
614 self.append_text_node(text);
615 }
616 }
617
618 pub fn append_node(&mut self, node: Node) {
632 self.children.push(node);
633 }
634
635 pub fn text(&self) -> String {
647 self.texts().fold(String::new(), |ret, new| ret + new)
648 }
649
650 pub fn get_child<'a, N: AsRef<str>, NS: Into<NSChoice<'a>>>(
667 &self,
668 name: N,
669 namespace: NS,
670 ) -> Option<&Element> {
671 let namespace = namespace.into();
672 for fork in &self.children {
673 if let Node::Element(ref e) = *fork {
674 if e.is(name.as_ref(), namespace) {
675 return Some(e);
676 }
677 }
678 }
679 None
680 }
681
682 pub fn get_child_mut<'a, N: AsRef<str>, NS: Into<NSChoice<'a>>>(
685 &mut self,
686 name: N,
687 namespace: NS,
688 ) -> Option<&mut Element> {
689 let namespace = namespace.into();
690 for fork in &mut self.children {
691 if let Node::Element(ref mut e) = *fork {
692 if e.is(name.as_ref(), namespace) {
693 return Some(e);
694 }
695 }
696 }
697 None
698 }
699
700 pub fn has_child<'a, N: AsRef<str>, NS: Into<NSChoice<'a>>>(
717 &self,
718 name: N,
719 namespace: NS,
720 ) -> bool {
721 self.get_child(name, namespace).is_some()
722 }
723
724 pub fn remove_child<'a, N: AsRef<str>, NS: Into<NSChoice<'a>>>(
739 &mut self,
740 name: N,
741 namespace: NS,
742 ) -> Option<Element> {
743 let name = name.as_ref();
744 let namespace = namespace.into();
745 let idx = self.children.iter().position(|x| {
746 if let Node::Element(ref elm) = x {
747 elm.is(name, namespace)
748 } else {
749 false
750 }
751 })?;
752 self.children.remove(idx).into_element()
753 }
754
755 pub fn unshift_child(&mut self) -> Option<Element> {
758 while !self.children.is_empty() {
759 if let Some(el) = self.children.remove(0).into_element() {
760 return Some(el);
761 }
762 }
763
764 None
765 }
766}
767
768pub struct Children<'a> {
770 iter: slice::Iter<'a, Node>,
771}
772
773impl<'a> Iterator for Children<'a> {
774 type Item = &'a Element;
775
776 fn next(&mut self) -> Option<&'a Element> {
777 for item in &mut self.iter {
778 if let Node::Element(ref child) = *item {
779 return Some(child);
780 }
781 }
782 None
783 }
784}
785
786pub struct ChildrenMut<'a> {
788 iter: slice::IterMut<'a, Node>,
789}
790
791impl<'a> Iterator for ChildrenMut<'a> {
792 type Item = &'a mut Element;
793
794 fn next(&mut self) -> Option<&'a mut Element> {
795 for item in &mut self.iter {
796 if let Node::Element(ref mut child) = *item {
797 return Some(child);
798 }
799 }
800 None
801 }
802}
803
804pub struct ContentsAsChildren<'a> {
806 iter: alloc::vec::Drain<'a, Node>,
807}
808
809impl Iterator for ContentsAsChildren<'_> {
810 type Item = Element;
811
812 fn next(&mut self) -> Option<Element> {
813 for item in &mut self.iter {
814 if let Node::Element(child) = item {
815 return Some(child);
816 }
817 }
818 None
819 }
820}
821
822pub struct Texts<'a> {
824 iter: slice::Iter<'a, Node>,
825}
826
827impl<'a> Iterator for Texts<'a> {
828 type Item = &'a str;
829
830 fn next(&mut self) -> Option<&'a str> {
831 for item in &mut self.iter {
832 if let Node::Text(ref child) = *item {
833 return Some(child);
834 }
835 }
836 None
837 }
838}
839
840pub struct TextsMut<'a> {
842 iter: slice::IterMut<'a, Node>,
843}
844
845impl<'a> Iterator for TextsMut<'a> {
846 type Item = &'a mut String;
847
848 fn next(&mut self) -> Option<&'a mut String> {
849 for item in &mut self.iter {
850 if let Node::Text(ref mut child) = *item {
851 return Some(child);
852 }
853 }
854 None
855 }
856}
857
858pub type Nodes<'a> = slice::Iter<'a, Node>;
860
861pub type NodesMut<'a> = slice::IterMut<'a, Node>;
863
864pub struct Attrs<'a> {
866 iter: btree_map::Iter<'a, String, String>,
867}
868
869impl<'a> Iterator for Attrs<'a> {
870 type Item = (&'a str, &'a str);
871
872 fn next(&mut self) -> Option<Self::Item> {
873 self.iter.next().map(|(x, y)| (x.as_ref(), y.as_ref()))
874 }
875}
876
877pub struct AttrsMut<'a> {
879 iter: btree_map::IterMut<'a, String, String>,
880}
881
882impl<'a> Iterator for AttrsMut<'a> {
883 type Item = (&'a str, &'a mut String);
884
885 fn next(&mut self) -> Option<Self::Item> {
886 self.iter.next().map(|(x, y)| (x.as_ref(), y))
887 }
888}
889
890pub struct ElementBuilder {
892 root: Element,
893}
894
895impl ElementBuilder {
896 pub fn prefix<S: Into<Namespace>>(
898 mut self,
899 prefix: Prefix,
900 namespace: S,
901 ) -> Result<ElementBuilder> {
902 if self.root.prefixes.get(&prefix).is_some() {
903 return Err(Error::DuplicatePrefix);
904 }
905 self.root.prefixes.insert(prefix, namespace.into());
906 Ok(self)
907 }
908
909 pub fn attr<S: Into<String>, V: IntoAttributeValue>(
911 mut self,
912 name: S,
913 value: V,
914 ) -> ElementBuilder {
915 self.root.set_attr(name, value);
916 self
917 }
918
919 pub fn append<T: Into<Node>>(mut self, node: T) -> ElementBuilder {
921 self.root.append_node(node.into());
922 self
923 }
924
925 pub fn append_all<T: Into<Node>, I: IntoIterator<Item = T>>(
927 mut self,
928 iter: I,
929 ) -> ElementBuilder {
930 for node in iter {
931 self.root.append_node(node.into());
932 }
933 self
934 }
935
936 pub fn build(self) -> Element {
938 self.root
939 }
940}
941
942#[cfg(test)]
943mod tests {
944 use super::*;
945
946 #[test]
947 fn test_element_new() {
948 let elem = Element::new(
949 "name".to_owned(),
950 "namespace".to_owned(),
951 (None, "namespace".to_owned()),
952 BTreeMap::from_iter(vec![("name".to_string(), "value".to_string())].into_iter()),
953 Vec::new(),
954 );
955
956 assert_eq!(elem.name(), "name");
957 assert_eq!(elem.ns(), "namespace".to_owned());
958 assert_eq!(elem.attr("name"), Some("value"));
959 assert_eq!(elem.attr("inexistent"), None);
960 }
961
962 #[test]
963 fn test_from_reader_simple() {
964 let xml = b"<foo xmlns='ns1'></foo>";
965 let elem = Element::from_reader(&xml[..]);
966
967 let elem2 = Element::builder("foo", "ns1").build();
968
969 assert_eq!(elem.unwrap(), elem2);
970 }
971
972 #[test]
973 fn test_from_reader_nested() {
974 let xml = b"<foo xmlns='ns1'><bar xmlns='ns1' baz='qxx' /></foo>";
975 let elem = Element::from_reader(&xml[..]);
976
977 let nested = Element::builder("bar", "ns1").attr("baz", "qxx").build();
978 let elem2 = Element::builder("foo", "ns1").append(nested).build();
979
980 assert_eq!(elem.unwrap(), elem2);
981 }
982
983 #[test]
984 fn test_from_reader_with_prefix() {
985 let xml = b"<foo xmlns='ns1'><prefix:bar xmlns:prefix='ns1' baz='qxx' /></foo>";
986 let elem = Element::from_reader(&xml[..]);
987
988 let nested = Element::builder("bar", "ns1").attr("baz", "qxx").build();
989 let elem2 = Element::builder("foo", "ns1").append(nested).build();
990
991 assert_eq!(elem.unwrap(), elem2);
992 }
993
994 #[test]
995 fn test_from_reader_split_prefix() {
996 let xml = b"<foo:bar xmlns:foo='ns1'/>";
997 let elem = Element::from_reader(&xml[..]).unwrap();
998
999 assert_eq!(elem.name(), String::from("bar"));
1000 assert_eq!(elem.ns(), String::from("ns1"));
1001 assert_eq!(
1003 elem.prefixes.get(&Some(String::from("foo"))),
1004 Some(&String::from("ns1"))
1005 );
1006 }
1007
1008 #[test]
1009 fn parses_spectest_xml() {
1010 let xml = br#"<rng:grammar xmlns:rng="http://relaxng.org/ns/structure/1.0">
1012 <rng:name xmlns:rng="http://relaxng.org/ns/structure/1.0"></rng:name>
1013 </rng:grammar>
1014 "#;
1015 let _ = Element::from_reader(&xml[..]).unwrap();
1016 }
1017
1018 #[test]
1019 fn does_not_unescape_cdata() {
1020 let xml = b"<test xmlns='test'><![CDATA['>blah<blah>]]></test>";
1021 let elem = Element::from_reader(&xml[..]).unwrap();
1022 assert_eq!(elem.text(), "'>blah<blah>");
1023 }
1024
1025 #[test]
1026 fn test_compare_all_ns() {
1027 let xml = b"<foo xmlns='foo' xmlns:bar='baz'><bar:meh xmlns:bar='baz' /></foo>";
1028 let elem = Element::from_reader(&xml[..]).unwrap();
1029
1030 let elem2 = elem.clone();
1031
1032 let xml3 = b"<foo xmlns='foo'><bar:meh xmlns:bar='baz'/></foo>";
1033 let elem3 = Element::from_reader(&xml3[..]).unwrap();
1034
1035 let xml4 = b"<prefix:foo xmlns:prefix='foo'><bar:meh xmlns:bar='baz'/></prefix:foo>";
1036 let elem4 = Element::from_reader(&xml4[..]).unwrap();
1037
1038 assert_eq!(elem, elem2);
1039 assert_eq!(elem, elem3);
1040 assert_eq!(elem, elem4);
1041 }
1042
1043 #[test]
1044 fn test_compare_empty_children() {
1045 let elem1 = Element::bare("p", "");
1046 let elem2 = Element::builder("p", "")
1047 .append(Node::Element(Element::bare("span", "")))
1048 .build();
1049
1050 assert_ne!(elem1, elem2);
1051 }
1052
1053 #[test]
1054 fn test_from_reader_with_prefixes() {
1055 let xml = b"<foo><bar xmlns='baz'/></foo>";
1056 let elem =
1057 Element::from_reader_with_prefixes(&xml[..], String::from("jabber:client")).unwrap();
1058
1059 let xml2 = b"<foo xmlns='jabber:client'><bar xmlns='baz'/></foo>";
1060 let elem2 = Element::from_reader(&xml2[..]).unwrap();
1061
1062 assert_eq!(elem, elem2);
1063 }
1064
1065 #[test]
1066 fn failure_with_duplicate_namespace() {
1067 let _: Element = r###"<?xml version="1.0" encoding="UTF-8"?>
1068 <wsdl:definitions
1069 xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
1070 xmlns:xsd="http://www.w3.org/2001/XMLSchema">
1071 <wsdl:types>
1072 <xsd:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
1073 </xsd:schema>
1074 </wsdl:types>
1075 </wsdl:definitions>
1076 "###
1077 .parse()
1078 .unwrap();
1079 }
1080}