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::slice;
27use core::str::FromStr;
28
29use std::borrow::Borrow;
30use std::hash::Hash;
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: String,
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,
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()
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: &'a NS,
263 name: &'a N,
264 ) -> Option<&'a str>
265 where
266 RxmlNamespace: 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>(&mut self, ns: RxmlNamespace, name: NcName, val: V) {
304 let val = val.into_attribute_value();
305
306 if let Some(value) = self.attributes.get_mut(&ns, &name) {
307 *value = val
308 .expect("removing existing value via set_attr, this is not yet supported (TODO)"); return;
310 }
311
312 if let Some(val) = val {
313 self.attributes.insert(ns.clone(), name, val);
314 }
315 }
316
317 pub fn is<'a, N: AsRef<str>, NS: Into<NSChoice<'a>>>(&self, name: N, namespace: NS) -> bool {
337 self.name == name.as_ref() && namespace.into().compare(self.namespace.as_ref())
338 }
339
340 pub fn has_ns<'a, NS: Into<NSChoice<'a>>>(&self, namespace: NS) -> bool {
358 namespace.into().compare(self.namespace.as_ref())
359 }
360
361 fn from_reader_inner<R: io::BufRead>(
362 mut tree_builder: TreeBuilder,
363 reader: R,
364 ) -> Result<Element> {
365 let mut driver = RawReader::new(reader);
366 while let Some(event) = driver.read()? {
367 tree_builder.process_event(event)?;
368
369 if let Some(root) = tree_builder.root.take() {
370 return Ok(root);
371 }
372 }
373 Err(Error::EndOfDocument)
374 }
375
376 pub fn from_reader<R: io::BufRead>(reader: R) -> Result<Element> {
378 Element::from_reader_inner(TreeBuilder::new(), reader)
379 }
380
381 pub fn from_reader_with_prefixes<R: io::BufRead, P: Into<Prefixes>>(
385 reader: R,
386 prefixes: P,
387 ) -> Result<Element> {
388 let tree_builder = TreeBuilder::new().with_prefixes_stack([prefixes.into()].into());
389 Element::from_reader_inner(tree_builder, reader)
390 }
391
392 pub fn write_to<W: io::Write>(&self, writer: &mut W) -> Result<()> {
394 self.to_writer(&mut ItemWriter::new(writer))
395 }
396
397 pub fn write_to_decl<W: io::Write>(&self, writer: &mut W) -> Result<()> {
399 self.to_writer_decl(&mut ItemWriter::new(writer))
400 }
401
402 pub fn to_writer<W: io::Write>(&self, writer: &mut ItemWriter<W>) -> Result<()> {
404 self.write_to_inner(writer)
405 }
406
407 pub fn to_writer_decl<W: io::Write>(&self, writer: &mut ItemWriter<W>) -> Result<()> {
409 writer
410 .write(Item::XmlDeclaration(XmlVersion::V1_0))
411 .unwrap(); self.write_to_inner(writer)
413 }
414
415 pub fn write_to_inner<W: io::Write>(&self, writer: &mut ItemWriter<W>) -> Result<()> {
417 for (prefix, namespace) in self.prefixes.declared_prefixes() {
418 assert!(writer.encoder.ns_tracker_mut().declare_fixed(
419 prefix.as_deref().map(TryInto::try_into).transpose()?,
420 namespace.clone().into(),
421 ));
422 }
423
424 let namespace: RxmlNamespace = self.namespace.clone().into();
425 writer.write(Item::ElementHeadStart(&namespace, (*self.name).try_into()?))?;
426
427 for ((ns, key), value) in &self.attributes {
428 writer.write(Item::Attribute(&ns, key, value))?;
429 }
430
431 if !self.children.is_empty() {
432 writer.write(Item::ElementHeadEnd)?;
433 for child in &self.children {
434 child.write_to_inner(writer)?;
435 }
436 }
437 writer.write(Item::ElementFoot)?;
438
439 Ok(())
440 }
441
442 pub fn take_nodes(&mut self) -> Vec<Node> {
444 self.children.drain(..).collect()
445 }
446
447 #[inline]
466 pub fn nodes(&self) -> Nodes<'_> {
467 self.children.iter()
468 }
469
470 #[inline]
472 pub fn nodes_mut(&mut self) -> NodesMut<'_> {
473 self.children.iter_mut()
474 }
475
476 #[inline]
492 #[must_use]
493 pub fn children(&self) -> Children<'_> {
494 Children {
495 iter: self.children.iter(),
496 }
497 }
498
499 #[inline]
501 #[must_use]
502 pub fn children_mut(&mut self) -> ChildrenMut<'_> {
503 ChildrenMut {
504 iter: self.children.iter_mut(),
505 }
506 }
507
508 #[inline]
517 #[doc(hidden)]
518 pub fn take_contents_as_children(&mut self) -> ContentsAsChildren<'_> {
519 ContentsAsChildren {
520 iter: self.children.drain(..),
521 }
522 }
523
524 #[inline]
539 #[must_use]
540 pub fn texts(&self) -> Texts<'_> {
541 Texts {
542 iter: self.children.iter(),
543 }
544 }
545
546 #[inline]
548 #[must_use]
549 pub fn texts_mut(&mut self) -> TextsMut<'_> {
550 TextsMut {
551 iter: self.children.iter_mut(),
552 }
553 }
554
555 pub fn append_child(&mut self, child: Element) -> &mut Element {
579 self.children.push(Node::Element(child));
580 if let Node::Element(ref mut cld) = *self.children.last_mut().unwrap() {
581 cld
582 } else {
583 unreachable!()
584 }
585 }
586
587 pub fn append_text_node<S: Into<String>>(&mut self, child: S) {
603 self.children.push(Node::Text(child.into()));
604 }
605
606 pub fn append_text<S: Into<String>>(&mut self, text: S) {
627 if let Some(Node::Text(ref mut child)) = self.children.last_mut() {
628 child.push_str(&text.into());
629 } else {
630 self.append_text_node(text);
631 }
632 }
633
634 pub fn append_node(&mut self, node: Node) {
648 self.children.push(node);
649 }
650
651 #[must_use]
663 pub fn text(&self) -> String {
664 self.texts().fold(String::new(), |ret, new| ret + new)
665 }
666
667 pub fn get_child<'a, N: AsRef<str>, NS: Into<NSChoice<'a>>>(
684 &self,
685 name: N,
686 namespace: NS,
687 ) -> Option<&Element> {
688 let namespace = namespace.into();
689 for fork in &self.children {
690 if let Node::Element(ref e) = *fork {
691 if e.is(name.as_ref(), namespace) {
692 return Some(e);
693 }
694 }
695 }
696 None
697 }
698
699 pub fn get_child_mut<'a, N: AsRef<str>, NS: Into<NSChoice<'a>>>(
702 &mut self,
703 name: N,
704 namespace: NS,
705 ) -> Option<&mut Element> {
706 let namespace = namespace.into();
707 for fork in &mut self.children {
708 if let Node::Element(ref mut e) = *fork {
709 if e.is(name.as_ref(), namespace) {
710 return Some(e);
711 }
712 }
713 }
714 None
715 }
716
717 pub fn has_child<'a, N: AsRef<str>, NS: Into<NSChoice<'a>>>(
734 &self,
735 name: N,
736 namespace: NS,
737 ) -> bool {
738 self.get_child(name, namespace).is_some()
739 }
740
741 pub fn remove_child<'a, N: AsRef<str>, NS: Into<NSChoice<'a>>>(
756 &mut self,
757 name: N,
758 namespace: NS,
759 ) -> Option<Element> {
760 let name = name.as_ref();
761 let namespace = namespace.into();
762 let idx = self.children.iter().position(|x| {
763 if let Node::Element(ref elm) = x {
764 elm.is(name, namespace)
765 } else {
766 false
767 }
768 })?;
769 self.children.remove(idx).into_element()
770 }
771
772 pub fn unshift_child(&mut self) -> Option<Element> {
775 while !self.children.is_empty() {
776 if let Some(el) = self.children.remove(0).into_element() {
777 return Some(el);
778 }
779 }
780
781 None
782 }
783}
784
785pub struct Children<'a> {
787 iter: slice::Iter<'a, Node>,
788}
789
790impl<'a> Iterator for Children<'a> {
791 type Item = &'a Element;
792
793 fn next(&mut self) -> Option<&'a Element> {
794 for item in &mut self.iter {
795 if let Node::Element(ref child) = *item {
796 return Some(child);
797 }
798 }
799 None
800 }
801}
802
803pub struct ChildrenMut<'a> {
805 iter: slice::IterMut<'a, Node>,
806}
807
808impl<'a> Iterator for ChildrenMut<'a> {
809 type Item = &'a mut Element;
810
811 fn next(&mut self) -> Option<&'a mut Element> {
812 for item in &mut self.iter {
813 if let Node::Element(ref mut child) = *item {
814 return Some(child);
815 }
816 }
817 None
818 }
819}
820
821pub struct ContentsAsChildren<'a> {
823 iter: alloc::vec::Drain<'a, Node>,
824}
825
826impl Iterator for ContentsAsChildren<'_> {
827 type Item = Element;
828
829 fn next(&mut self) -> Option<Element> {
830 for item in &mut self.iter {
831 if let Node::Element(child) = item {
832 return Some(child);
833 }
834 }
835 None
836 }
837}
838
839pub struct Texts<'a> {
841 iter: slice::Iter<'a, Node>,
842}
843
844impl<'a> Iterator for Texts<'a> {
845 type Item = &'a str;
846
847 fn next(&mut self) -> Option<&'a str> {
848 for item in &mut self.iter {
849 if let Node::Text(ref child) = *item {
850 return Some(child);
851 }
852 }
853 None
854 }
855}
856
857pub struct TextsMut<'a> {
859 iter: slice::IterMut<'a, Node>,
860}
861
862impl<'a> Iterator for TextsMut<'a> {
863 type Item = &'a mut String;
864
865 fn next(&mut self) -> Option<&'a mut String> {
866 for item in &mut self.iter {
867 if let Node::Text(ref mut child) = *item {
868 return Some(child);
869 }
870 }
871 None
872 }
873}
874
875pub type Nodes<'a> = slice::Iter<'a, Node>;
877
878pub type NodesMut<'a> = slice::IterMut<'a, Node>;
880
881pub struct ElementBuilder {
883 root: Element,
884}
885
886impl ElementBuilder {
887 pub fn prefix<S: Into<Namespace>>(
889 mut self,
890 prefix: Prefix,
891 namespace: S,
892 ) -> Result<ElementBuilder> {
893 if self.root.prefixes.get(&prefix).is_some() {
894 return Err(Error::DuplicatePrefix);
895 }
896 self.root.prefixes.insert(prefix, namespace.into());
897 Ok(self)
898 }
899
900 #[must_use]
902 pub fn attr<V: IntoAttributeValue>(mut self, name: NcName, value: V) -> ElementBuilder {
903 self.root.set_attr(RxmlNamespace::NONE, name, value);
904 self
905 }
906
907 #[must_use]
909 pub fn attr_ns<V: IntoAttributeValue>(
910 mut self,
911 ns: RxmlNamespace,
912 name: NcName,
913 value: V,
914 ) -> ElementBuilder {
915 self.root.set_attr(ns, name, value);
916 self
917 }
918
919 #[must_use]
921 pub fn append<T: Into<Node>>(mut self, node: T) -> ElementBuilder {
922 self.root.append_node(node.into());
923 self
924 }
925
926 #[must_use]
928 pub fn append_all<T: Into<Node>, I: IntoIterator<Item = T>>(
929 mut self,
930 iter: I,
931 ) -> ElementBuilder {
932 for node in iter {
933 self.root.append_node(node.into());
934 }
935 self
936 }
937
938 #[must_use]
940 pub fn build(self) -> Element {
941 self.root
942 }
943}
944
945#[cfg(test)]
946mod tests {
947 use super::*;
948 use rxml::xml_ncname;
949 use std::collections::BTreeMap;
950
951 #[test]
952 fn test_element_new() {
953 let mut attrs = AttrMap::new();
954 attrs.insert(
955 String::from("namespace").into(),
956 xml_ncname!("name").to_owned(),
957 "value".to_string(),
958 );
959 let elem = Element::new(
960 "name".to_owned(),
961 "namespace".to_owned(),
962 (None, "namespace".to_owned()),
963 attrs,
964 Vec::new(),
965 );
966
967 assert_eq!(elem.name(), "name");
968 assert_eq!(elem.ns(), "namespace".to_owned());
969 assert_eq!(elem.attr_ns("namespace", "name"), Some("value"));
970 assert_eq!(elem.attr("inexistent"), None);
971 }
972
973 #[test]
974 fn test_from_reader_simple() {
975 let xml = b"<foo xmlns='ns1'></foo>";
976 let elem = Element::from_reader(&xml[..]);
977
978 let elem2 = Element::builder("foo", "ns1").build();
979
980 assert_eq!(elem.unwrap(), elem2);
981 }
982
983 #[test]
984 fn test_from_reader_nested() {
985 let xml = b"<foo xmlns='ns1'><bar xmlns='ns1' baz='qxx' /></foo>";
986 let elem = Element::from_reader(&xml[..]);
987
988 let nested = Element::builder("bar", "ns1")
989 .attr(xml_ncname!("baz").to_owned(), "qxx")
990 .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")
1002 .attr(xml_ncname!("baz").to_owned(), "qxx")
1003 .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 test_from_reader_with_prefixes_serialization() {
1082 let prefixes: BTreeMap<Option<String>, String> = {
1083 let mut tmp = BTreeMap::new();
1084 tmp.insert(None, String::from("foo"));
1085 tmp.insert(Some(String::from("test")), String::from("bar"));
1086 tmp
1087 };
1088
1089 let input = r#"<foo test:attr="true"><bar/></foo>"#;
1090 let output = r#"<foo xmlns='foo' xmlns:test='bar' test:attr='true'><bar/></foo>"#;
1091
1092 let elem = Element::from_reader_with_prefixes(input.as_ref(), prefixes).unwrap();
1093 assert_eq!(String::from(&elem), output);
1094 }
1095
1096 #[test]
1097 fn failure_with_duplicate_namespace() {
1098 let _: Element = r###"<?xml version="1.0" encoding="UTF-8"?>
1099 <wsdl:definitions
1100 xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
1101 xmlns:xsd="http://www.w3.org/2001/XMLSchema">
1102 <wsdl:types>
1103 <xsd:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
1104 </xsd:schema>
1105 </wsdl:types>
1106 </wsdl:definitions>
1107 "###
1108 .parse()
1109 .unwrap();
1110 }
1111}