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::collections::btree_map::{self, BTreeMap};
24use alloc::string::String;
25use alloc::vec::Vec;
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
73#[must_use]
77pub fn escape(raw: &[u8]) -> Cow<'_, [u8]> {
78 fn to_escape(b: u8) -> bool {
79 matches!(b, b'<' | b'>' | b'\'' | b'&' | b'"')
80 }
81
82 let mut escapes: Vec<(usize, &'static [u8])> = Vec::new();
83 let mut bytes = raw.iter();
84 let mut loc = 0;
85 while let Some(i) = bytes.position(|&b| to_escape(b)) {
86 loc += i;
87 match raw[loc] {
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 b'"' => escapes.push((loc, b""")),
93 _ => unreachable!("Only '<', '>', '\'', '&' and '\"' are escaped"),
94 }
95 loc += 1;
96 }
97
98 if escapes.is_empty() {
99 Cow::Borrowed(raw)
100 } else {
101 let len = raw.len();
102 let mut v = Vec::with_capacity(len);
103 let mut start = 0;
104 for (i, r) in escapes {
105 v.extend_from_slice(&raw[start..i]);
106 v.extend_from_slice(r);
107 start = i + 1;
108 }
109
110 if start < len {
111 v.extend_from_slice(&raw[start..]);
112 }
113 Cow::Owned(v)
114 }
115}
116
117#[derive(Clone, Eq, Debug)]
118pub struct Element {
120 name: String,
121 namespace: String,
122 pub prefixes: Prefixes,
124 attributes: BTreeMap<String, String>,
125 children: Vec<Node>,
126}
127
128impl<'a> From<&'a Element> for String {
129 fn from(elem: &'a Element) -> String {
130 let mut writer = Vec::new();
131 elem.write_to(&mut writer).unwrap();
132 String::from_utf8(writer).unwrap()
133 }
134}
135
136impl FromStr for Element {
137 type Err = Error;
138
139 fn from_str(s: &str) -> Result<Element> {
140 Element::from_reader(s.as_bytes())
141 }
142}
143
144impl PartialEq for Element {
145 fn eq(&self, other: &Self) -> bool {
146 if self.name() == other.name() && self.ns() == other.ns() && self.attrs().eq(other.attrs())
147 {
148 if self.nodes().count() != other.nodes().count() {
149 return false;
150 }
151 self.nodes()
152 .zip(other.nodes())
153 .all(|(node1, node2)| node1 == node2)
154 } else {
155 false
156 }
157 }
158}
159
160impl Element {
161 pub(crate) fn new<P: Into<Prefixes>>(
162 name: String,
163 namespace: String,
164 prefixes: P,
165 attributes: BTreeMap<String, String>,
166 children: Vec<Node>,
167 ) -> Element {
168 Element {
169 name,
170 namespace,
171 prefixes: prefixes.into(),
172 attributes,
173 children,
174 }
175 }
176
177 pub fn builder<S: AsRef<str>, NS: Into<String>>(name: S, namespace: NS) -> ElementBuilder {
196 ElementBuilder {
197 root: Element::new(
198 name.as_ref().to_string(),
199 namespace.into(),
200 None,
201 BTreeMap::new(),
202 Vec::new(),
203 ),
204 }
205 }
206
207 pub fn bare<S: Into<String>, NS: Into<String>>(name: S, namespace: NS) -> Element {
222 Element::new(
223 name.into(),
224 namespace.into(),
225 None,
226 BTreeMap::new(),
227 Vec::new(),
228 )
229 }
230
231 #[must_use]
233 pub fn name(&self) -> &str {
234 &self.name
235 }
236
237 #[must_use]
239 pub fn ns(&self) -> String {
240 self.namespace.clone()
241 }
242
243 #[must_use]
245 pub fn attr(&self, name: &str) -> Option<&str> {
246 if let Some(value) = self.attributes.get(name) {
247 return Some(value);
248 }
249 None
250 }
251
252 #[must_use]
267 pub fn attrs(&self) -> Attrs<'_> {
268 Attrs {
269 iter: self.attributes.iter(),
270 }
271 }
272
273 #[must_use]
276 pub fn attrs_mut(&mut self) -> AttrsMut<'_> {
277 AttrsMut {
278 iter: self.attributes.iter_mut(),
279 }
280 }
281
282 pub fn set_attr<S: Into<String>, V: IntoAttributeValue>(&mut self, name: S, val: V) {
284 let name = name.into();
285 let val = val.into_attribute_value();
286
287 if let Some(value) = self.attributes.get_mut(&name) {
288 *value = val
289 .expect("removing existing value via set_attr, this is not yet supported (TODO)"); return;
291 }
292
293 if let Some(val) = val {
294 self.attributes.insert(name, val);
295 }
296 }
297
298 pub fn is<'a, N: AsRef<str>, NS: Into<NSChoice<'a>>>(&self, name: N, namespace: NS) -> bool {
318 self.name == name.as_ref() && namespace.into().compare(self.namespace.as_ref())
319 }
320
321 pub fn has_ns<'a, NS: Into<NSChoice<'a>>>(&self, namespace: NS) -> bool {
339 namespace.into().compare(self.namespace.as_ref())
340 }
341
342 fn from_reader_inner<R: io::BufRead>(
343 mut tree_builder: TreeBuilder,
344 reader: R,
345 ) -> Result<Element> {
346 let mut driver = RawReader::new(reader);
347 while let Some(event) = driver.read()? {
348 tree_builder.process_event(event)?;
349
350 if let Some(root) = tree_builder.root.take() {
351 return Ok(root);
352 }
353 }
354 Err(Error::EndOfDocument)
355 }
356
357 pub fn from_reader<R: io::BufRead>(reader: R) -> Result<Element> {
359 Element::from_reader_inner(TreeBuilder::new(), reader)
360 }
361
362 pub fn from_reader_with_prefixes<R: io::BufRead, P: Into<Prefixes>>(
366 reader: R,
367 prefixes: P,
368 ) -> Result<Element> {
369 let tree_builder = TreeBuilder::new().with_prefixes_stack([prefixes.into()].into());
370 Element::from_reader_inner(tree_builder, reader)
371 }
372
373 pub fn write_to<W: io::Write>(&self, writer: &mut W) -> Result<()> {
375 self.to_writer(&mut ItemWriter::new(writer))
376 }
377
378 pub fn write_to_decl<W: io::Write>(&self, writer: &mut W) -> Result<()> {
380 self.to_writer_decl(&mut ItemWriter::new(writer))
381 }
382
383 pub fn to_writer<W: io::Write>(&self, writer: &mut ItemWriter<W>) -> Result<()> {
385 self.write_to_inner(writer)
386 }
387
388 pub fn to_writer_decl<W: io::Write>(&self, writer: &mut ItemWriter<W>) -> Result<()> {
390 writer
391 .write(Item::XmlDeclaration(XmlVersion::V1_0))
392 .unwrap(); self.write_to_inner(writer)
394 }
395
396 pub fn write_to_inner<W: io::Write>(&self, writer: &mut ItemWriter<W>) -> Result<()> {
398 for (prefix, namespace) in self.prefixes.declared_prefixes() {
399 assert!(writer.encoder.ns_tracker_mut().declare_fixed(
400 prefix.as_deref().map(TryInto::try_into).transpose()?,
401 namespace.clone().into(),
402 ));
403 }
404
405 let namespace: RxmlNamespace = self.namespace.clone().into();
406 writer.write(Item::ElementHeadStart(&namespace, (*self.name).try_into()?))?;
407
408 for (key, value) in &self.attributes {
409 let (prefix, name) = <&rxml::NameStr>::try_from(&**key)
410 .unwrap()
411 .split_name()
412 .unwrap();
413 let namespace = match prefix {
414 Some(prefix) => match writer.encoder.ns_tracker().lookup_prefix(Some(prefix)) {
415 Ok(v) => v,
416 Err(rxml::writer::PrefixError::Undeclared) => return Err(Error::InvalidPrefix),
417 },
418 None => RxmlNamespace::NONE,
419 };
420 writer.write(Item::Attribute(&namespace, name, value))?;
421 }
422
423 if !self.children.is_empty() {
424 writer.write(Item::ElementHeadEnd)?;
425 for child in &self.children {
426 child.write_to_inner(writer)?;
427 }
428 }
429 writer.write(Item::ElementFoot)?;
430
431 Ok(())
432 }
433
434 pub fn take_nodes(&mut self) -> Vec<Node> {
436 self.children.drain(..).collect()
437 }
438
439 #[inline]
458 pub fn nodes(&self) -> Nodes<'_> {
459 self.children.iter()
460 }
461
462 #[inline]
464 pub fn nodes_mut(&mut self) -> NodesMut<'_> {
465 self.children.iter_mut()
466 }
467
468 #[inline]
484 #[must_use]
485 pub fn children(&self) -> Children<'_> {
486 Children {
487 iter: self.children.iter(),
488 }
489 }
490
491 #[inline]
493 #[must_use]
494 pub fn children_mut(&mut self) -> ChildrenMut<'_> {
495 ChildrenMut {
496 iter: self.children.iter_mut(),
497 }
498 }
499
500 #[inline]
509 #[doc(hidden)]
510 pub fn take_contents_as_children(&mut self) -> ContentsAsChildren<'_> {
511 ContentsAsChildren {
512 iter: self.children.drain(..),
513 }
514 }
515
516 #[inline]
531 #[must_use]
532 pub fn texts(&self) -> Texts<'_> {
533 Texts {
534 iter: self.children.iter(),
535 }
536 }
537
538 #[inline]
540 #[must_use]
541 pub fn texts_mut(&mut self) -> TextsMut<'_> {
542 TextsMut {
543 iter: self.children.iter_mut(),
544 }
545 }
546
547 pub fn append_child(&mut self, child: Element) -> &mut Element {
571 self.children.push(Node::Element(child));
572 if let Node::Element(ref mut cld) = *self.children.last_mut().unwrap() {
573 cld
574 } else {
575 unreachable!()
576 }
577 }
578
579 pub fn append_text_node<S: Into<String>>(&mut self, child: S) {
595 self.children.push(Node::Text(child.into()));
596 }
597
598 pub fn append_text<S: Into<String>>(&mut self, text: S) {
619 if let Some(Node::Text(ref mut child)) = self.children.last_mut() {
620 child.push_str(&text.into());
621 } else {
622 self.append_text_node(text);
623 }
624 }
625
626 pub fn append_node(&mut self, node: Node) {
640 self.children.push(node);
641 }
642
643 #[must_use]
655 pub fn text(&self) -> String {
656 self.texts().fold(String::new(), |ret, new| ret + new)
657 }
658
659 pub fn get_child<'a, N: AsRef<str>, NS: Into<NSChoice<'a>>>(
676 &self,
677 name: N,
678 namespace: NS,
679 ) -> Option<&Element> {
680 let namespace = namespace.into();
681 for fork in &self.children {
682 if let Node::Element(ref e) = *fork {
683 if e.is(name.as_ref(), namespace) {
684 return Some(e);
685 }
686 }
687 }
688 None
689 }
690
691 pub fn get_child_mut<'a, N: AsRef<str>, NS: Into<NSChoice<'a>>>(
694 &mut self,
695 name: N,
696 namespace: NS,
697 ) -> Option<&mut Element> {
698 let namespace = namespace.into();
699 for fork in &mut self.children {
700 if let Node::Element(ref mut e) = *fork {
701 if e.is(name.as_ref(), namespace) {
702 return Some(e);
703 }
704 }
705 }
706 None
707 }
708
709 pub fn has_child<'a, N: AsRef<str>, NS: Into<NSChoice<'a>>>(
726 &self,
727 name: N,
728 namespace: NS,
729 ) -> bool {
730 self.get_child(name, namespace).is_some()
731 }
732
733 pub fn remove_child<'a, N: AsRef<str>, NS: Into<NSChoice<'a>>>(
748 &mut self,
749 name: N,
750 namespace: NS,
751 ) -> Option<Element> {
752 let name = name.as_ref();
753 let namespace = namespace.into();
754 let idx = self.children.iter().position(|x| {
755 if let Node::Element(ref elm) = x {
756 elm.is(name, namespace)
757 } else {
758 false
759 }
760 })?;
761 self.children.remove(idx).into_element()
762 }
763
764 pub fn unshift_child(&mut self) -> Option<Element> {
767 while !self.children.is_empty() {
768 if let Some(el) = self.children.remove(0).into_element() {
769 return Some(el);
770 }
771 }
772
773 None
774 }
775}
776
777pub struct Children<'a> {
779 iter: slice::Iter<'a, Node>,
780}
781
782impl<'a> Iterator for Children<'a> {
783 type Item = &'a Element;
784
785 fn next(&mut self) -> Option<&'a Element> {
786 for item in &mut self.iter {
787 if let Node::Element(ref child) = *item {
788 return Some(child);
789 }
790 }
791 None
792 }
793}
794
795pub struct ChildrenMut<'a> {
797 iter: slice::IterMut<'a, Node>,
798}
799
800impl<'a> Iterator for ChildrenMut<'a> {
801 type Item = &'a mut Element;
802
803 fn next(&mut self) -> Option<&'a mut Element> {
804 for item in &mut self.iter {
805 if let Node::Element(ref mut child) = *item {
806 return Some(child);
807 }
808 }
809 None
810 }
811}
812
813pub struct ContentsAsChildren<'a> {
815 iter: alloc::vec::Drain<'a, Node>,
816}
817
818impl Iterator for ContentsAsChildren<'_> {
819 type Item = Element;
820
821 fn next(&mut self) -> Option<Element> {
822 for item in &mut self.iter {
823 if let Node::Element(child) = item {
824 return Some(child);
825 }
826 }
827 None
828 }
829}
830
831pub struct Texts<'a> {
833 iter: slice::Iter<'a, Node>,
834}
835
836impl<'a> Iterator for Texts<'a> {
837 type Item = &'a str;
838
839 fn next(&mut self) -> Option<&'a str> {
840 for item in &mut self.iter {
841 if let Node::Text(ref child) = *item {
842 return Some(child);
843 }
844 }
845 None
846 }
847}
848
849pub struct TextsMut<'a> {
851 iter: slice::IterMut<'a, Node>,
852}
853
854impl<'a> Iterator for TextsMut<'a> {
855 type Item = &'a mut String;
856
857 fn next(&mut self) -> Option<&'a mut String> {
858 for item in &mut self.iter {
859 if let Node::Text(ref mut child) = *item {
860 return Some(child);
861 }
862 }
863 None
864 }
865}
866
867pub type Nodes<'a> = slice::Iter<'a, Node>;
869
870pub type NodesMut<'a> = slice::IterMut<'a, Node>;
872
873pub struct Attrs<'a> {
875 iter: btree_map::Iter<'a, String, String>,
876}
877
878impl<'a> Iterator for Attrs<'a> {
879 type Item = (&'a str, &'a str);
880
881 fn next(&mut self) -> Option<Self::Item> {
882 self.iter.next().map(|(x, y)| (x.as_ref(), y.as_ref()))
883 }
884}
885
886pub struct AttrsMut<'a> {
888 iter: btree_map::IterMut<'a, String, String>,
889}
890
891impl<'a> Iterator for AttrsMut<'a> {
892 type Item = (&'a str, &'a mut String);
893
894 fn next(&mut self) -> Option<Self::Item> {
895 self.iter.next().map(|(x, y)| (x.as_ref(), y))
896 }
897}
898
899pub struct ElementBuilder {
901 root: Element,
902}
903
904impl ElementBuilder {
905 pub fn prefix<S: Into<Namespace>>(
907 mut self,
908 prefix: Prefix,
909 namespace: S,
910 ) -> Result<ElementBuilder> {
911 if self.root.prefixes.get(&prefix).is_some() {
912 return Err(Error::DuplicatePrefix);
913 }
914 self.root.prefixes.insert(prefix, namespace.into());
915 Ok(self)
916 }
917
918 #[must_use]
920 pub fn attr<S: Into<String>, V: IntoAttributeValue>(
921 mut self,
922 name: S,
923 value: V,
924 ) -> ElementBuilder {
925 self.root.set_attr(name, value);
926 self
927 }
928
929 #[must_use]
931 pub fn append<T: Into<Node>>(mut self, node: T) -> ElementBuilder {
932 self.root.append_node(node.into());
933 self
934 }
935
936 #[must_use]
938 pub fn append_all<T: Into<Node>, I: IntoIterator<Item = T>>(
939 mut self,
940 iter: I,
941 ) -> ElementBuilder {
942 for node in iter {
943 self.root.append_node(node.into());
944 }
945 self
946 }
947
948 #[must_use]
950 pub fn build(self) -> Element {
951 self.root
952 }
953}
954
955#[cfg(test)]
956mod tests {
957 use super::*;
958
959 #[test]
960 fn test_element_new() {
961 let elem = Element::new(
962 "name".to_owned(),
963 "namespace".to_owned(),
964 (None, "namespace".to_owned()),
965 BTreeMap::from_iter([("name".to_string(), "value".to_string())].into_iter()),
966 Vec::new(),
967 );
968
969 assert_eq!(elem.name(), "name");
970 assert_eq!(elem.ns(), "namespace".to_owned());
971 assert_eq!(elem.attr("name"), Some("value"));
972 assert_eq!(elem.attr("inexistent"), None);
973 }
974
975 #[test]
976 fn test_from_reader_simple() {
977 let xml = b"<foo xmlns='ns1'></foo>";
978 let elem = Element::from_reader(&xml[..]);
979
980 let elem2 = Element::builder("foo", "ns1").build();
981
982 assert_eq!(elem.unwrap(), elem2);
983 }
984
985 #[test]
986 fn test_from_reader_nested() {
987 let xml = b"<foo xmlns='ns1'><bar xmlns='ns1' baz='qxx' /></foo>";
988 let elem = Element::from_reader(&xml[..]);
989
990 let nested = Element::builder("bar", "ns1").attr("baz", "qxx").build();
991 let elem2 = Element::builder("foo", "ns1").append(nested).build();
992
993 assert_eq!(elem.unwrap(), elem2);
994 }
995
996 #[test]
997 fn test_from_reader_with_prefix() {
998 let xml = b"<foo xmlns='ns1'><prefix:bar xmlns:prefix='ns1' baz='qxx' /></foo>";
999 let elem = Element::from_reader(&xml[..]);
1000
1001 let nested = Element::builder("bar", "ns1").attr("baz", "qxx").build();
1002 let elem2 = Element::builder("foo", "ns1").append(nested).build();
1003
1004 assert_eq!(elem.unwrap(), elem2);
1005 }
1006
1007 #[test]
1008 fn test_from_reader_split_prefix() {
1009 let xml = b"<foo:bar xmlns:foo='ns1'/>";
1010 let elem = Element::from_reader(&xml[..]).unwrap();
1011
1012 assert_eq!(elem.name(), String::from("bar"));
1013 assert_eq!(elem.ns(), String::from("ns1"));
1014 assert_eq!(
1016 elem.prefixes.get(&Some(String::from("foo"))),
1017 Some(&String::from("ns1"))
1018 );
1019 }
1020
1021 #[test]
1022 fn parses_spectest_xml() {
1023 let xml = br#"<rng:grammar xmlns:rng="http://relaxng.org/ns/structure/1.0">
1025 <rng:name xmlns:rng="http://relaxng.org/ns/structure/1.0"></rng:name>
1026 </rng:grammar>
1027 "#;
1028 let _ = Element::from_reader(&xml[..]).unwrap();
1029 }
1030
1031 #[test]
1032 fn does_not_unescape_cdata() {
1033 let xml = b"<test xmlns='test'><![CDATA['>blah<blah>]]></test>";
1034 let elem = Element::from_reader(&xml[..]).unwrap();
1035 assert_eq!(elem.text(), "'>blah<blah>");
1036 }
1037
1038 #[test]
1039 fn test_compare_all_ns() {
1040 let xml = b"<foo xmlns='foo' xmlns:bar='baz'><bar:meh xmlns:bar='baz' /></foo>";
1041 let elem = Element::from_reader(&xml[..]).unwrap();
1042
1043 let elem2 = elem.clone();
1044
1045 let xml3 = b"<foo xmlns='foo'><bar:meh xmlns:bar='baz'/></foo>";
1046 let elem3 = Element::from_reader(&xml3[..]).unwrap();
1047
1048 let xml4 = b"<prefix:foo xmlns:prefix='foo'><bar:meh xmlns:bar='baz'/></prefix:foo>";
1049 let elem4 = Element::from_reader(&xml4[..]).unwrap();
1050
1051 assert_eq!(elem, elem2);
1052 assert_eq!(elem, elem3);
1053 assert_eq!(elem, elem4);
1054 }
1055
1056 #[test]
1057 fn test_compare_empty_children() {
1058 let elem1 = Element::bare("p", "");
1059 let elem2 = Element::builder("p", "")
1060 .append(Node::Element(Element::bare("span", "")))
1061 .build();
1062
1063 assert_ne!(elem1, elem2);
1064 }
1065
1066 #[test]
1067 fn test_from_reader_with_prefixes() {
1068 let xml = b"<foo><bar xmlns='baz'/></foo>";
1069 let elem =
1070 Element::from_reader_with_prefixes(&xml[..], String::from("jabber:client")).unwrap();
1071
1072 let xml2 = b"<foo xmlns='jabber:client'><bar xmlns='baz'/></foo>";
1073 let elem2 = Element::from_reader(&xml2[..]).unwrap();
1074
1075 assert_eq!(elem, elem2);
1076 }
1077
1078 #[test]
1079 fn test_from_reader_with_prefixes_serialization() {
1080 let prefixes: BTreeMap<Option<String>, String> = {
1081 let mut tmp = BTreeMap::new();
1082 tmp.insert(None, String::from("foo"));
1083 tmp.insert(Some(String::from("test")), String::from("bar"));
1084 tmp
1085 };
1086
1087 let input = r#"<foo test:attr="true"><bar/></foo>"#;
1088 let output = r#"<foo xmlns='foo' xmlns:test='bar' test:attr='true'><bar/></foo>"#;
1089
1090 let elem = Element::from_reader_with_prefixes(input.as_ref(), prefixes).unwrap();
1091 assert_eq!(String::from(&elem), output);
1092 }
1093
1094 #[test]
1095 fn failure_with_duplicate_namespace() {
1096 let _: Element = r###"<?xml version="1.0" encoding="UTF-8"?>
1097 <wsdl:definitions
1098 xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
1099 xmlns:xsd="http://www.w3.org/2001/XMLSchema">
1100 <wsdl:types>
1101 <xsd:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
1102 </xsd:schema>
1103 </wsdl:types>
1104 </wsdl:definitions>
1105 "###
1106 .parse()
1107 .unwrap();
1108 }
1109}