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 pub fn from_reader<R: io::BufRead>(reader: R) -> Result<Element> {
344 let mut tree_builder = TreeBuilder::new();
345 let mut driver = RawReader::new(reader);
346 while let Some(event) = driver.read()? {
347 tree_builder.process_event(event)?;
348
349 if let Some(root) = tree_builder.root.take() {
350 return Ok(root);
351 }
352 }
353 Err(Error::EndOfDocument)
354 }
355
356 pub fn from_reader_with_prefixes<R: io::BufRead, P: Into<Prefixes>>(
360 reader: R,
361 prefixes: P,
362 ) -> Result<Element> {
363 let mut tree_builder = TreeBuilder::new().with_prefixes_stack([prefixes.into()].into());
364 let mut driver = RawReader::new(reader);
365 while let Some(event) = driver.read()? {
366 tree_builder.process_event(event)?;
367
368 if let Some(root) = tree_builder.root.take() {
369 return Ok(root);
370 }
371 }
372 Err(Error::EndOfDocument)
373 }
374
375 pub fn write_to<W: io::Write>(&self, writer: &mut W) -> Result<()> {
377 self.to_writer(&mut ItemWriter::new(writer))
378 }
379
380 pub fn write_to_decl<W: io::Write>(&self, writer: &mut W) -> Result<()> {
382 self.to_writer_decl(&mut ItemWriter::new(writer))
383 }
384
385 pub fn to_writer<W: io::Write>(&self, writer: &mut ItemWriter<W>) -> Result<()> {
387 self.write_to_inner(writer)
388 }
389
390 pub fn to_writer_decl<W: io::Write>(&self, writer: &mut ItemWriter<W>) -> Result<()> {
392 writer
393 .write(Item::XmlDeclaration(XmlVersion::V1_0))
394 .unwrap(); self.write_to_inner(writer)
396 }
397
398 pub fn write_to_inner<W: io::Write>(&self, writer: &mut ItemWriter<W>) -> Result<()> {
400 for (prefix, namespace) in self.prefixes.declared_prefixes() {
401 assert!(writer.encoder.ns_tracker_mut().declare_fixed(
402 prefix.as_ref().map(|x| (&**x).try_into()).transpose()?,
403 namespace.clone().into(),
404 ));
405 }
406
407 let namespace: RxmlNamespace = self.namespace.clone().into();
408 writer.write(Item::ElementHeadStart(&namespace, (*self.name).try_into()?))?;
409
410 for (key, value) in &self.attributes {
411 let (prefix, name) = <&rxml::NameStr>::try_from(&**key)
412 .unwrap()
413 .split_name()
414 .unwrap();
415 let namespace = match prefix {
416 Some(prefix) => match writer.encoder.ns_tracker().lookup_prefix(Some(prefix)) {
417 Ok(v) => v,
418 Err(rxml::writer::PrefixError::Undeclared) => return Err(Error::InvalidPrefix),
419 },
420 None => RxmlNamespace::NONE,
421 };
422 writer.write(Item::Attribute(&namespace, name, value))?;
423 }
424
425 if !self.children.is_empty() {
426 writer.write(Item::ElementHeadEnd)?;
427 for child in &self.children {
428 child.write_to_inner(writer)?;
429 }
430 }
431 writer.write(Item::ElementFoot)?;
432
433 Ok(())
434 }
435
436 pub fn take_nodes(&mut self) -> Vec<Node> {
438 self.children.drain(..).collect()
439 }
440
441 #[inline]
460 pub fn nodes(&self) -> Nodes {
461 self.children.iter()
462 }
463
464 #[inline]
466 pub fn nodes_mut(&mut self) -> NodesMut {
467 self.children.iter_mut()
468 }
469
470 #[inline]
486 #[must_use]
487 pub fn children(&self) -> Children {
488 Children {
489 iter: self.children.iter(),
490 }
491 }
492
493 #[inline]
495 #[must_use]
496 pub fn children_mut(&mut self) -> ChildrenMut {
497 ChildrenMut {
498 iter: self.children.iter_mut(),
499 }
500 }
501
502 #[inline]
511 #[doc(hidden)]
512 pub fn take_contents_as_children(&mut self) -> ContentsAsChildren {
513 ContentsAsChildren {
514 iter: self.children.drain(..),
515 }
516 }
517
518 #[inline]
533 #[must_use]
534 pub fn texts(&self) -> Texts {
535 Texts {
536 iter: self.children.iter(),
537 }
538 }
539
540 #[inline]
542 #[must_use]
543 pub fn texts_mut(&mut self) -> TextsMut {
544 TextsMut {
545 iter: self.children.iter_mut(),
546 }
547 }
548
549 pub fn append_child(&mut self, child: Element) -> &mut Element {
573 self.children.push(Node::Element(child));
574 if let Node::Element(ref mut cld) = *self.children.last_mut().unwrap() {
575 cld
576 } else {
577 unreachable!()
578 }
579 }
580
581 pub fn append_text_node<S: Into<String>>(&mut self, child: S) {
597 self.children.push(Node::Text(child.into()));
598 }
599
600 pub fn append_text<S: Into<String>>(&mut self, text: S) {
621 if let Some(Node::Text(ref mut child)) = self.children.last_mut() {
622 child.push_str(&text.into());
623 } else {
624 self.append_text_node(text);
625 }
626 }
627
628 pub fn append_node(&mut self, node: Node) {
642 self.children.push(node);
643 }
644
645 #[must_use]
657 pub fn text(&self) -> String {
658 self.texts().fold(String::new(), |ret, new| ret + new)
659 }
660
661 pub fn get_child<'a, N: AsRef<str>, NS: Into<NSChoice<'a>>>(
678 &self,
679 name: N,
680 namespace: NS,
681 ) -> Option<&Element> {
682 let namespace = namespace.into();
683 for fork in &self.children {
684 if let Node::Element(ref e) = *fork {
685 if e.is(name.as_ref(), namespace) {
686 return Some(e);
687 }
688 }
689 }
690 None
691 }
692
693 pub fn get_child_mut<'a, N: AsRef<str>, NS: Into<NSChoice<'a>>>(
696 &mut self,
697 name: N,
698 namespace: NS,
699 ) -> Option<&mut Element> {
700 let namespace = namespace.into();
701 for fork in &mut self.children {
702 if let Node::Element(ref mut e) = *fork {
703 if e.is(name.as_ref(), namespace) {
704 return Some(e);
705 }
706 }
707 }
708 None
709 }
710
711 pub fn has_child<'a, N: AsRef<str>, NS: Into<NSChoice<'a>>>(
728 &self,
729 name: N,
730 namespace: NS,
731 ) -> bool {
732 self.get_child(name, namespace).is_some()
733 }
734
735 pub fn remove_child<'a, N: AsRef<str>, NS: Into<NSChoice<'a>>>(
750 &mut self,
751 name: N,
752 namespace: NS,
753 ) -> Option<Element> {
754 let name = name.as_ref();
755 let namespace = namespace.into();
756 let idx = self.children.iter().position(|x| {
757 if let Node::Element(ref elm) = x {
758 elm.is(name, namespace)
759 } else {
760 false
761 }
762 })?;
763 self.children.remove(idx).into_element()
764 }
765
766 pub fn unshift_child(&mut self) -> Option<Element> {
769 while !self.children.is_empty() {
770 if let Some(el) = self.children.remove(0).into_element() {
771 return Some(el);
772 }
773 }
774
775 None
776 }
777}
778
779pub struct Children<'a> {
781 iter: slice::Iter<'a, Node>,
782}
783
784impl<'a> Iterator for Children<'a> {
785 type Item = &'a Element;
786
787 fn next(&mut self) -> Option<&'a Element> {
788 for item in &mut self.iter {
789 if let Node::Element(ref child) = *item {
790 return Some(child);
791 }
792 }
793 None
794 }
795}
796
797pub struct ChildrenMut<'a> {
799 iter: slice::IterMut<'a, Node>,
800}
801
802impl<'a> Iterator for ChildrenMut<'a> {
803 type Item = &'a mut Element;
804
805 fn next(&mut self) -> Option<&'a mut Element> {
806 for item in &mut self.iter {
807 if let Node::Element(ref mut child) = *item {
808 return Some(child);
809 }
810 }
811 None
812 }
813}
814
815pub struct ContentsAsChildren<'a> {
817 iter: alloc::vec::Drain<'a, Node>,
818}
819
820impl Iterator for ContentsAsChildren<'_> {
821 type Item = Element;
822
823 fn next(&mut self) -> Option<Element> {
824 for item in &mut self.iter {
825 if let Node::Element(child) = item {
826 return Some(child);
827 }
828 }
829 None
830 }
831}
832
833pub struct Texts<'a> {
835 iter: slice::Iter<'a, Node>,
836}
837
838impl<'a> Iterator for Texts<'a> {
839 type Item = &'a str;
840
841 fn next(&mut self) -> Option<&'a str> {
842 for item in &mut self.iter {
843 if let Node::Text(ref child) = *item {
844 return Some(child);
845 }
846 }
847 None
848 }
849}
850
851pub struct TextsMut<'a> {
853 iter: slice::IterMut<'a, Node>,
854}
855
856impl<'a> Iterator for TextsMut<'a> {
857 type Item = &'a mut String;
858
859 fn next(&mut self) -> Option<&'a mut String> {
860 for item in &mut self.iter {
861 if let Node::Text(ref mut child) = *item {
862 return Some(child);
863 }
864 }
865 None
866 }
867}
868
869pub type Nodes<'a> = slice::Iter<'a, Node>;
871
872pub type NodesMut<'a> = slice::IterMut<'a, Node>;
874
875pub struct Attrs<'a> {
877 iter: btree_map::Iter<'a, String, String>,
878}
879
880impl<'a> Iterator for Attrs<'a> {
881 type Item = (&'a str, &'a str);
882
883 fn next(&mut self) -> Option<Self::Item> {
884 self.iter.next().map(|(x, y)| (x.as_ref(), y.as_ref()))
885 }
886}
887
888pub struct AttrsMut<'a> {
890 iter: btree_map::IterMut<'a, String, String>,
891}
892
893impl<'a> Iterator for AttrsMut<'a> {
894 type Item = (&'a str, &'a mut String);
895
896 fn next(&mut self) -> Option<Self::Item> {
897 self.iter.next().map(|(x, y)| (x.as_ref(), y))
898 }
899}
900
901pub struct ElementBuilder {
903 root: Element,
904}
905
906impl ElementBuilder {
907 pub fn prefix<S: Into<Namespace>>(
909 mut self,
910 prefix: Prefix,
911 namespace: S,
912 ) -> Result<ElementBuilder> {
913 if self.root.prefixes.get(&prefix).is_some() {
914 return Err(Error::DuplicatePrefix);
915 }
916 self.root.prefixes.insert(prefix, namespace.into());
917 Ok(self)
918 }
919
920 #[must_use]
922 pub fn attr<S: Into<String>, V: IntoAttributeValue>(
923 mut self,
924 name: S,
925 value: V,
926 ) -> ElementBuilder {
927 self.root.set_attr(name, value);
928 self
929 }
930
931 #[must_use]
933 pub fn append<T: Into<Node>>(mut self, node: T) -> ElementBuilder {
934 self.root.append_node(node.into());
935 self
936 }
937
938 #[must_use]
940 pub fn append_all<T: Into<Node>, I: IntoIterator<Item = T>>(
941 mut self,
942 iter: I,
943 ) -> ElementBuilder {
944 for node in iter {
945 self.root.append_node(node.into());
946 }
947 self
948 }
949
950 #[must_use]
952 pub fn build(self) -> Element {
953 self.root
954 }
955}
956
957#[cfg(test)]
958mod tests {
959 use super::*;
960
961 #[test]
962 fn test_element_new() {
963 let elem = Element::new(
964 "name".to_owned(),
965 "namespace".to_owned(),
966 (None, "namespace".to_owned()),
967 BTreeMap::from_iter([("name".to_string(), "value".to_string())].into_iter()),
968 Vec::new(),
969 );
970
971 assert_eq!(elem.name(), "name");
972 assert_eq!(elem.ns(), "namespace".to_owned());
973 assert_eq!(elem.attr("name"), Some("value"));
974 assert_eq!(elem.attr("inexistent"), None);
975 }
976
977 #[test]
978 fn test_from_reader_simple() {
979 let xml = b"<foo xmlns='ns1'></foo>";
980 let elem = Element::from_reader(&xml[..]);
981
982 let elem2 = Element::builder("foo", "ns1").build();
983
984 assert_eq!(elem.unwrap(), elem2);
985 }
986
987 #[test]
988 fn test_from_reader_nested() {
989 let xml = b"<foo xmlns='ns1'><bar xmlns='ns1' baz='qxx' /></foo>";
990 let elem = Element::from_reader(&xml[..]);
991
992 let nested = Element::builder("bar", "ns1").attr("baz", "qxx").build();
993 let elem2 = Element::builder("foo", "ns1").append(nested).build();
994
995 assert_eq!(elem.unwrap(), elem2);
996 }
997
998 #[test]
999 fn test_from_reader_with_prefix() {
1000 let xml = b"<foo xmlns='ns1'><prefix:bar xmlns:prefix='ns1' baz='qxx' /></foo>";
1001 let elem = Element::from_reader(&xml[..]);
1002
1003 let nested = Element::builder("bar", "ns1").attr("baz", "qxx").build();
1004 let elem2 = Element::builder("foo", "ns1").append(nested).build();
1005
1006 assert_eq!(elem.unwrap(), elem2);
1007 }
1008
1009 #[test]
1010 fn test_from_reader_split_prefix() {
1011 let xml = b"<foo:bar xmlns:foo='ns1'/>";
1012 let elem = Element::from_reader(&xml[..]).unwrap();
1013
1014 assert_eq!(elem.name(), String::from("bar"));
1015 assert_eq!(elem.ns(), String::from("ns1"));
1016 assert_eq!(
1018 elem.prefixes.get(&Some(String::from("foo"))),
1019 Some(&String::from("ns1"))
1020 );
1021 }
1022
1023 #[test]
1024 fn parses_spectest_xml() {
1025 let xml = br#"<rng:grammar xmlns:rng="http://relaxng.org/ns/structure/1.0">
1027 <rng:name xmlns:rng="http://relaxng.org/ns/structure/1.0"></rng:name>
1028 </rng:grammar>
1029 "#;
1030 let _ = Element::from_reader(&xml[..]).unwrap();
1031 }
1032
1033 #[test]
1034 fn does_not_unescape_cdata() {
1035 let xml = b"<test xmlns='test'><![CDATA['>blah<blah>]]></test>";
1036 let elem = Element::from_reader(&xml[..]).unwrap();
1037 assert_eq!(elem.text(), "'>blah<blah>");
1038 }
1039
1040 #[test]
1041 fn test_compare_all_ns() {
1042 let xml = b"<foo xmlns='foo' xmlns:bar='baz'><bar:meh xmlns:bar='baz' /></foo>";
1043 let elem = Element::from_reader(&xml[..]).unwrap();
1044
1045 let elem2 = elem.clone();
1046
1047 let xml3 = b"<foo xmlns='foo'><bar:meh xmlns:bar='baz'/></foo>";
1048 let elem3 = Element::from_reader(&xml3[..]).unwrap();
1049
1050 let xml4 = b"<prefix:foo xmlns:prefix='foo'><bar:meh xmlns:bar='baz'/></prefix:foo>";
1051 let elem4 = Element::from_reader(&xml4[..]).unwrap();
1052
1053 assert_eq!(elem, elem2);
1054 assert_eq!(elem, elem3);
1055 assert_eq!(elem, elem4);
1056 }
1057
1058 #[test]
1059 fn test_compare_empty_children() {
1060 let elem1 = Element::bare("p", "");
1061 let elem2 = Element::builder("p", "")
1062 .append(Node::Element(Element::bare("span", "")))
1063 .build();
1064
1065 assert_ne!(elem1, elem2);
1066 }
1067
1068 #[test]
1069 fn test_from_reader_with_prefixes() {
1070 let xml = b"<foo><bar xmlns='baz'/></foo>";
1071 let elem =
1072 Element::from_reader_with_prefixes(&xml[..], String::from("jabber:client")).unwrap();
1073
1074 let xml2 = b"<foo xmlns='jabber:client'><bar xmlns='baz'/></foo>";
1075 let elem2 = Element::from_reader(&xml2[..]).unwrap();
1076
1077 assert_eq!(elem, elem2);
1078 }
1079
1080 #[test]
1081 fn failure_with_duplicate_namespace() {
1082 let _: Element = r###"<?xml version="1.0" encoding="UTF-8"?>
1083 <wsdl:definitions
1084 xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
1085 xmlns:xsd="http://www.w3.org/2001/XMLSchema">
1086 <wsdl:types>
1087 <xsd:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
1088 </xsd:schema>
1089 </wsdl:types>
1090 </wsdl:definitions>
1091 "###
1092 .parse()
1093 .unwrap();
1094 }
1095}