1use std::borrow::Cow;
4use std::io::Write;
5use std::result::Result as StdResult;
6
7use crate::encoding::UTF8_BOM;
8use crate::errors::{Error, Result};
9use crate::events::{attributes::Attribute, BytesCData, BytesStart, BytesText, Event};
10
11#[cfg(feature = "async-tokio")]
12mod async_tokio;
13
14#[cfg(feature = "serialize")]
16use {crate::de::DeError, serde::Serialize};
17
18#[derive(Clone)]
65pub struct Writer<W> {
66 writer: W,
68 indent: Option<Indentation>,
69}
70
71impl<W> Writer<W> {
72 pub fn new(inner: W) -> Writer<W> {
74 Writer {
75 writer: inner,
76 indent: None,
77 }
78 }
79
80 pub fn new_with_indent(inner: W, indent_char: u8, indent_size: usize) -> Writer<W> {
82 Writer {
83 writer: inner,
84 indent: Some(Indentation::new(indent_char, indent_size)),
85 }
86 }
87
88 pub fn into_inner(self) -> W {
90 self.writer
91 }
92
93 pub fn get_mut(&mut self) -> &mut W {
95 &mut self.writer
96 }
97
98 pub fn get_ref(&self) -> &W {
100 &self.writer
101 }
102
103 #[must_use]
147 pub fn create_element<'a, N>(&'a mut self, name: N) -> ElementWriter<W>
148 where
149 N: Into<Cow<'a, str>>,
150 {
151 ElementWriter {
152 writer: self,
153 start_tag: BytesStart::new(name),
154 state: AttributeIndent::NoneAttributesWritten,
155 spaces: Vec::new(),
156 }
157 }
158}
159
160impl<W: Write> Writer<W> {
161 pub fn write_bom(&mut self) -> Result<()> {
192 self.write(UTF8_BOM)
193 }
194
195 pub fn write_event<'a, E: AsRef<Event<'a>>>(&mut self, event: E) -> Result<()> {
197 let mut next_should_line_break = true;
198 let result = match *event.as_ref() {
199 Event::Start(ref e) => {
200 let result = self.write_wrapped(b"<", e, b">");
201 if let Some(i) = self.indent.as_mut() {
202 i.grow();
203 }
204 result
205 }
206 Event::End(ref e) => {
207 if let Some(i) = self.indent.as_mut() {
208 i.shrink();
209 }
210 self.write_wrapped(b"</", e, b">")
211 }
212 Event::Empty(ref e) => self.write_wrapped(b"<", e, b"/>"),
213 Event::Text(ref e) => {
214 next_should_line_break = false;
215 self.write(e)
216 }
217 Event::Comment(ref e) => self.write_wrapped(b"<!--", e, b"-->"),
218 Event::CData(ref e) => {
219 next_should_line_break = false;
220 self.write(b"<![CDATA[")?;
221 self.write(e)?;
222 self.write(b"]]>")
223 }
224 Event::Decl(ref e) => self.write_wrapped(b"<?", e, b"?>"),
225 Event::PI(ref e) => self.write_wrapped(b"<?", e, b"?>"),
226 Event::DocType(ref e) => self.write_wrapped(b"<!DOCTYPE ", e, b">"),
227 Event::Eof => Ok(()),
228 };
229 if let Some(i) = self.indent.as_mut() {
230 i.should_line_break = next_should_line_break;
231 }
232 result
233 }
234
235 #[inline]
237 pub(crate) fn write(&mut self, value: &[u8]) -> Result<()> {
238 self.writer.write_all(value).map_err(Into::into)
239 }
240
241 #[inline]
242 fn write_wrapped(&mut self, before: &[u8], value: &[u8], after: &[u8]) -> Result<()> {
243 if let Some(ref i) = self.indent {
244 if i.should_line_break {
245 self.writer.write_all(b"\n")?;
246 self.writer.write_all(i.current())?;
247 }
248 }
249 self.write(before)?;
250 self.write(value)?;
251 self.write(after)?;
252 Ok(())
253 }
254
255 pub fn write_indent(&mut self) -> Result<()> {
267 if let Some(ref i) = self.indent {
268 self.writer.write_all(b"\n")?;
269 self.writer.write_all(i.current())?;
270 }
271 Ok(())
272 }
273
274 #[cfg(feature = "serialize")]
320 pub fn write_serializable<T: Serialize>(
321 &mut self,
322 tag_name: &str,
323 content: &T,
324 ) -> std::result::Result<(), DeError> {
325 use crate::se::{Indent, Serializer};
326
327 self.write_indent()?;
328 let mut fmt = ToFmtWrite(&mut self.writer);
329 let mut serializer = Serializer::with_root(&mut fmt, Some(tag_name))?;
330
331 if let Some(indent) = &mut self.indent {
332 serializer.set_indent(Indent::Borrow(indent));
333 }
334
335 content.serialize(serializer)?;
336
337 Ok(())
338 }
339}
340
341#[derive(Debug)]
362enum AttributeIndent {
363 NoneAttributesWritten,
365 WriteSpaces(usize),
367 Spaces(usize),
369 WriteConfigured(usize),
371 Configured(usize),
373}
374
375pub struct ElementWriter<'a, W> {
378 writer: &'a mut Writer<W>,
379 start_tag: BytesStart<'a>,
380 state: AttributeIndent,
381 spaces: Vec<u8>,
383}
384
385impl<'a, W> ElementWriter<'a, W> {
386 pub fn with_attribute<'b, I>(mut self, attr: I) -> Self
388 where
389 I: Into<Attribute<'b>>,
390 {
391 self.write_attr(attr.into());
392 self
393 }
394
395 pub fn with_attributes<'b, I>(mut self, attributes: I) -> Self
399 where
400 I: IntoIterator,
401 I::Item: Into<Attribute<'b>>,
402 {
403 let mut iter = attributes.into_iter();
404 if let Some(attr) = iter.next() {
405 self.write_attr(attr.into());
406 self.start_tag.extend_attributes(iter);
407 }
408 self
409 }
410
411 pub fn new_line(mut self) -> Self {
453 if let Some(i) = self.writer.indent.as_mut() {
454 match self.state {
455 AttributeIndent::NoneAttributesWritten => {
458 self.state = AttributeIndent::WriteConfigured(i.indent_size)
459 }
460
461 AttributeIndent::WriteSpaces(_) => {}
462 AttributeIndent::Spaces(indent) => {
466 self.state = AttributeIndent::WriteSpaces(indent)
467 }
468
469 AttributeIndent::WriteConfigured(_) => {}
470 AttributeIndent::Configured(indent) => {
474 self.state = AttributeIndent::WriteConfigured(indent)
475 }
476 }
477 self.start_tag.push_newline();
478 };
479 self
480 }
481
482 fn write_attr<'b>(&mut self, attr: Attribute<'b>) {
484 if let Some(i) = self.writer.indent.as_mut() {
485 self.state = match self.state {
487 AttributeIndent::NoneAttributesWritten => {
491 self.start_tag.push_attribute(attr);
492 AttributeIndent::Spaces(self.start_tag.name().as_ref().len() + 2)
493 }
494
495 AttributeIndent::WriteSpaces(indent) => {
498 if self.spaces.len() < indent {
499 self.spaces.resize(indent, b' ');
500 }
501 self.start_tag.push_indent(&self.spaces[..indent]);
502 self.start_tag.push_attr(attr.into());
503 AttributeIndent::Spaces(indent)
504 }
505 AttributeIndent::Spaces(indent) => {
508 self.start_tag.push_attribute(attr);
509 AttributeIndent::Spaces(indent)
510 }
511
512 AttributeIndent::WriteConfigured(indent) => {
515 self.start_tag.push_indent(i.additional(indent));
516 self.start_tag.push_attr(attr.into());
517 AttributeIndent::Configured(indent)
518 }
519 AttributeIndent::Configured(indent) => {
522 self.start_tag.push_attribute(attr);
523 AttributeIndent::Configured(indent)
524 }
525 };
526 } else {
527 self.start_tag.push_attribute(attr);
528 }
529 }
530}
531
532impl<'a, W: Write> ElementWriter<'a, W> {
533 pub fn write_text_content(self, text: BytesText) -> Result<&'a mut Writer<W>> {
535 self.writer
536 .write_event(Event::Start(self.start_tag.borrow()))?;
537 self.writer.write_event(Event::Text(text))?;
538 self.writer
539 .write_event(Event::End(self.start_tag.to_end()))?;
540 Ok(self.writer)
541 }
542
543 pub fn write_cdata_content(self, text: BytesCData) -> Result<&'a mut Writer<W>> {
545 self.writer
546 .write_event(Event::Start(self.start_tag.borrow()))?;
547 self.writer.write_event(Event::CData(text))?;
548 self.writer
549 .write_event(Event::End(self.start_tag.to_end()))?;
550 Ok(self.writer)
551 }
552
553 pub fn write_pi_content(self, text: BytesText) -> Result<&'a mut Writer<W>> {
555 self.writer
556 .write_event(Event::Start(self.start_tag.borrow()))?;
557 self.writer.write_event(Event::PI(text))?;
558 self.writer
559 .write_event(Event::End(self.start_tag.to_end()))?;
560 Ok(self.writer)
561 }
562
563 pub fn write_empty(self) -> Result<&'a mut Writer<W>> {
565 self.writer.write_event(Event::Empty(self.start_tag))?;
566 Ok(self.writer)
567 }
568
569 pub fn write_inner_content<F, E>(self, closure: F) -> StdResult<&'a mut Writer<W>, E>
571 where
572 F: FnOnce(&mut Writer<W>) -> StdResult<(), E>,
573 E: From<Error>,
574 {
575 self.writer
576 .write_event(Event::Start(self.start_tag.borrow()))?;
577 closure(self.writer)?;
578 self.writer
579 .write_event(Event::End(self.start_tag.to_end()))?;
580 Ok(self.writer)
581 }
582}
583#[cfg(feature = "serialize")]
584struct ToFmtWrite<T>(pub T);
585
586#[cfg(feature = "serialize")]
587impl<T> std::fmt::Write for ToFmtWrite<T>
588where
589 T: std::io::Write,
590{
591 fn write_str(&mut self, s: &str) -> std::fmt::Result {
592 self.0.write_all(s.as_bytes()).map_err(|_| std::fmt::Error)
593 }
594}
595
596#[derive(Clone)]
597pub(crate) struct Indentation {
598 should_line_break: bool,
601 indent_char: u8,
603 indent_size: usize,
605 indents: Vec<u8>,
607 current_indent_len: usize,
609}
610
611impl Indentation {
612 pub fn new(indent_char: u8, indent_size: usize) -> Self {
613 Self {
614 should_line_break: false,
615 indent_char,
616 indent_size,
617 indents: vec![indent_char; 128],
618 current_indent_len: 0, }
620 }
621
622 pub fn grow(&mut self) {
624 self.current_indent_len += self.indent_size;
625 self.ensure(self.current_indent_len);
626 }
627
628 pub fn shrink(&mut self) {
630 self.current_indent_len = self.current_indent_len.saturating_sub(self.indent_size);
631 }
632
633 pub fn current(&self) -> &[u8] {
635 &self.indents[..self.current_indent_len]
636 }
637
638 pub fn additional(&mut self, additional_indent: usize) -> &[u8] {
640 let new_len = self.current_indent_len + additional_indent;
641 self.ensure(new_len);
642 &self.indents[..new_len]
643 }
644
645 fn ensure(&mut self, new_len: usize) {
646 if self.indents.len() < new_len {
647 self.indents.resize(new_len, self.indent_char);
648 }
649 }
650}
651
652#[cfg(test)]
653mod indentation {
654 use super::*;
655 use crate::events::*;
656 use pretty_assertions::assert_eq;
657
658 #[test]
659 fn self_closed() {
660 let mut buffer = Vec::new();
661 let mut writer = Writer::new_with_indent(&mut buffer, b' ', 4);
662
663 let tag = BytesStart::new("self-closed")
664 .with_attributes(vec![("attr1", "value1"), ("attr2", "value2")].into_iter());
665 writer
666 .write_event(Event::Empty(tag))
667 .expect("write tag failed");
668
669 assert_eq!(
670 std::str::from_utf8(&buffer).unwrap(),
671 r#"<self-closed attr1="value1" attr2="value2"/>"#
672 );
673 }
674
675 #[test]
676 fn empty_paired() {
677 let mut buffer = Vec::new();
678 let mut writer = Writer::new_with_indent(&mut buffer, b' ', 4);
679
680 let start = BytesStart::new("paired")
681 .with_attributes(vec![("attr1", "value1"), ("attr2", "value2")].into_iter());
682 let end = start.to_end();
683 writer
684 .write_event(Event::Start(start.clone()))
685 .expect("write start tag failed");
686 writer
687 .write_event(Event::End(end))
688 .expect("write end tag failed");
689
690 assert_eq!(
691 std::str::from_utf8(&buffer).unwrap(),
692 r#"<paired attr1="value1" attr2="value2">
693</paired>"#
694 );
695 }
696
697 #[test]
698 fn paired_with_inner() {
699 let mut buffer = Vec::new();
700 let mut writer = Writer::new_with_indent(&mut buffer, b' ', 4);
701
702 let start = BytesStart::new("paired")
703 .with_attributes(vec![("attr1", "value1"), ("attr2", "value2")].into_iter());
704 let end = start.to_end();
705 let inner = BytesStart::new("inner");
706
707 writer
708 .write_event(Event::Start(start.clone()))
709 .expect("write start tag failed");
710 writer
711 .write_event(Event::Empty(inner))
712 .expect("write inner tag failed");
713 writer
714 .write_event(Event::End(end))
715 .expect("write end tag failed");
716
717 assert_eq!(
718 std::str::from_utf8(&buffer).unwrap(),
719 r#"<paired attr1="value1" attr2="value2">
720 <inner/>
721</paired>"#
722 );
723 }
724
725 #[test]
726 fn paired_with_text() {
727 let mut buffer = Vec::new();
728 let mut writer = Writer::new_with_indent(&mut buffer, b' ', 4);
729
730 let start = BytesStart::new("paired")
731 .with_attributes(vec![("attr1", "value1"), ("attr2", "value2")].into_iter());
732 let end = start.to_end();
733 let text = BytesText::new("text");
734
735 writer
736 .write_event(Event::Start(start.clone()))
737 .expect("write start tag failed");
738 writer
739 .write_event(Event::Text(text))
740 .expect("write text failed");
741 writer
742 .write_event(Event::End(end))
743 .expect("write end tag failed");
744
745 assert_eq!(
746 std::str::from_utf8(&buffer).unwrap(),
747 r#"<paired attr1="value1" attr2="value2">text</paired>"#
748 );
749 }
750
751 #[test]
752 fn mixed_content() {
753 let mut buffer = Vec::new();
754 let mut writer = Writer::new_with_indent(&mut buffer, b' ', 4);
755
756 let start = BytesStart::new("paired")
757 .with_attributes(vec![("attr1", "value1"), ("attr2", "value2")].into_iter());
758 let end = start.to_end();
759 let text = BytesText::new("text");
760 let inner = BytesStart::new("inner");
761
762 writer
763 .write_event(Event::Start(start.clone()))
764 .expect("write start tag failed");
765 writer
766 .write_event(Event::Text(text))
767 .expect("write text failed");
768 writer
769 .write_event(Event::Empty(inner))
770 .expect("write inner tag failed");
771 writer
772 .write_event(Event::End(end))
773 .expect("write end tag failed");
774
775 assert_eq!(
776 std::str::from_utf8(&buffer).unwrap(),
777 r#"<paired attr1="value1" attr2="value2">text<inner/>
778</paired>"#
779 );
780 }
781
782 #[test]
783 fn nested() {
784 let mut buffer = Vec::new();
785 let mut writer = Writer::new_with_indent(&mut buffer, b' ', 4);
786
787 let start = BytesStart::new("paired")
788 .with_attributes(vec![("attr1", "value1"), ("attr2", "value2")].into_iter());
789 let end = start.to_end();
790 let inner = BytesStart::new("inner");
791
792 writer
793 .write_event(Event::Start(start.clone()))
794 .expect("write start 1 tag failed");
795 writer
796 .write_event(Event::Start(start.clone()))
797 .expect("write start 2 tag failed");
798 writer
799 .write_event(Event::Empty(inner))
800 .expect("write inner tag failed");
801 writer
802 .write_event(Event::End(end.clone()))
803 .expect("write end tag 2 failed");
804 writer
805 .write_event(Event::End(end))
806 .expect("write end tag 1 failed");
807
808 assert_eq!(
809 std::str::from_utf8(&buffer).unwrap(),
810 r#"<paired attr1="value1" attr2="value2">
811 <paired attr1="value1" attr2="value2">
812 <inner/>
813 </paired>
814</paired>"#
815 );
816 }
817
818 #[cfg(feature = "serialize")]
819 #[test]
820 fn serializable() {
821 #[derive(Serialize)]
822 struct Foo {
823 #[serde(rename = "@attribute")]
824 attribute: &'static str,
825
826 element: Bar,
827 list: Vec<&'static str>,
828
829 #[serde(rename = "$text")]
830 text: &'static str,
831
832 val: String,
833 }
834
835 #[derive(Serialize)]
836 struct Bar {
837 baz: usize,
838 bat: usize,
839 }
840
841 let mut buffer = Vec::new();
842 let mut writer = Writer::new_with_indent(&mut buffer, b' ', 4);
843
844 let content = Foo {
845 attribute: "attribute",
846 element: Bar { baz: 42, bat: 43 },
847 list: vec!["first element", "second element"],
848 text: "text",
849 val: "foo".to_owned(),
850 };
851
852 let start = BytesStart::new("paired")
853 .with_attributes(vec![("attr1", "value1"), ("attr2", "value2")].into_iter());
854 let end = start.to_end();
855
856 writer
857 .write_event(Event::Start(start.clone()))
858 .expect("write start tag failed");
859 writer
860 .write_serializable("foo_element", &content)
861 .expect("write serializable inner contents failed");
862 writer
863 .write_event(Event::End(end))
864 .expect("write end tag failed");
865
866 assert_eq!(
867 std::str::from_utf8(&buffer).unwrap(),
868 r#"<paired attr1="value1" attr2="value2">
869 <foo_element attribute="attribute">
870 <element>
871 <baz>42</baz>
872 <bat>43</bat>
873 </element>
874 <list>first element</list>
875 <list>second element</list>
876 text
877 <val>foo</val>
878 </foo_element>
879</paired>"#
880 );
881 }
882
883 #[test]
884 fn element_writer_empty() {
885 let mut buffer = Vec::new();
886 let mut writer = Writer::new_with_indent(&mut buffer, b' ', 4);
887
888 writer
889 .create_element("empty")
890 .with_attribute(("attr1", "value1"))
891 .with_attribute(("attr2", "value2"))
892 .write_empty()
893 .expect("failure");
894
895 assert_eq!(
896 std::str::from_utf8(&buffer).unwrap(),
897 r#"<empty attr1="value1" attr2="value2"/>"#
898 );
899 }
900
901 #[test]
902 fn element_writer_text() {
903 let mut buffer = Vec::new();
904 let mut writer = Writer::new_with_indent(&mut buffer, b' ', 4);
905
906 writer
907 .create_element("paired")
908 .with_attribute(("attr1", "value1"))
909 .with_attribute(("attr2", "value2"))
910 .write_text_content(BytesText::new("text"))
911 .expect("failure");
912
913 assert_eq!(
914 std::str::from_utf8(&buffer).unwrap(),
915 r#"<paired attr1="value1" attr2="value2">text</paired>"#
916 );
917 }
918
919 #[test]
920 fn element_writer_nested() {
921 let mut buffer = Vec::new();
922 let mut writer = Writer::new_with_indent(&mut buffer, b' ', 4);
923
924 writer
925 .create_element("outer")
926 .with_attribute(("attr1", "value1"))
927 .with_attribute(("attr2", "value2"))
928 .write_inner_content::<_, Error>(|writer| {
929 let fruits = ["apple", "orange", "banana"];
930 for (quant, item) in fruits.iter().enumerate() {
931 writer
932 .create_element("fruit")
933 .with_attribute(("quantity", quant.to_string().as_str()))
934 .write_text_content(BytesText::new(item))?;
935 }
936 writer
937 .create_element("inner")
938 .write_inner_content(|writer| {
939 writer.create_element("empty").write_empty().map(|_| ())
940 })?;
941
942 Ok(())
943 })
944 .expect("failure");
945
946 assert_eq!(
947 std::str::from_utf8(&buffer).unwrap(),
948 r#"<outer attr1="value1" attr2="value2">
949 <fruit quantity="0">apple</fruit>
950 <fruit quantity="1">orange</fruit>
951 <fruit quantity="2">banana</fruit>
952 <inner>
953 <empty/>
954 </inner>
955</outer>"#
956 );
957 }
958
959 mod in_attributes {
960 use super::*;
961 use pretty_assertions::assert_eq;
962
963 #[test]
964 fn newline_first() {
965 let mut buffer = Vec::new();
966 let mut writer = Writer::new_with_indent(&mut buffer, b'_', 1);
967
968 writer
969 .create_element("element")
970 .new_line()
971 .with_attribute(("first", "1"))
972 .with_attribute(("second", "2"))
973 .new_line()
974 .with_attribute(("third", "3"))
975 .with_attribute(("fourth", "4"))
976 .write_empty()
977 .expect("write tag failed");
978
979 assert_eq!(
980 std::str::from_utf8(&buffer).unwrap(),
981 "<element\
982 \n_first=\"1\" second=\"2\"\
983 \n_third=\"3\" fourth=\"4\"/>"
984 );
985 }
986
987 #[test]
988 fn newline_inside() {
989 let mut buffer = Vec::new();
990 let mut writer = Writer::new_with_indent(&mut buffer, b'_', 1);
991
992 writer
993 .create_element("element")
994 .with_attribute(("first", "1"))
995 .with_attribute(("second", "2"))
996 .new_line()
997 .with_attribute(("third", "3"))
998 .with_attribute(("fourth", "4"))
999 .write_empty()
1000 .expect("write tag failed");
1001
1002 assert_eq!(
1003 std::str::from_utf8(&buffer).unwrap(),
1004 "<element first=\"1\" second=\"2\"\
1005 \n third=\"3\" fourth=\"4\"/>"
1006 );
1007 }
1008
1009 #[test]
1010 fn newline_last() {
1011 let mut buffer = Vec::new();
1012 let mut writer = Writer::new_with_indent(&mut buffer, b'_', 1);
1013
1014 writer
1015 .create_element("element")
1016 .new_line()
1017 .with_attribute(("first", "1"))
1018 .with_attribute(("second", "2"))
1019 .new_line()
1020 .with_attribute(("third", "3"))
1021 .with_attribute(("fourth", "4"))
1022 .new_line()
1023 .write_empty()
1024 .expect("write tag failed");
1025
1026 writer
1027 .create_element("element")
1028 .with_attribute(("first", "1"))
1029 .with_attribute(("second", "2"))
1030 .new_line()
1031 .with_attribute(("third", "3"))
1032 .with_attribute(("fourth", "4"))
1033 .new_line()
1034 .write_empty()
1035 .expect("write tag failed");
1036
1037 assert_eq!(
1038 std::str::from_utf8(&buffer).unwrap(),
1039 "<element\
1040 \n_first=\"1\" second=\"2\"\
1041 \n_third=\"3\" fourth=\"4\"\
1042 \n/>\
1043 \n<element first=\"1\" second=\"2\"\
1044 \n third=\"3\" fourth=\"4\"\
1045 \n/>"
1046 );
1047 }
1048
1049 #[test]
1050 fn newline_twice() {
1051 let mut buffer = Vec::new();
1052 let mut writer = Writer::new_with_indent(&mut buffer, b'_', 1);
1053
1054 writer
1055 .create_element("element")
1056 .new_line()
1057 .new_line()
1058 .write_empty()
1059 .expect("write tag failed");
1060
1061 writer
1062 .create_element("element")
1063 .with_attribute(("first", "1"))
1064 .new_line()
1065 .new_line()
1066 .with_attribute(("second", "2"))
1067 .write_empty()
1068 .expect("write tag failed");
1069
1070 assert_eq!(
1071 std::str::from_utf8(&buffer).unwrap(),
1072 r#"<element
1073
1074/>
1075<element first="1"
1076
1077 second="2"/>"#
1078 );
1079 }
1080
1081 #[test]
1082 fn without_indent() {
1083 let mut buffer = Vec::new();
1084 let mut writer = Writer::new(&mut buffer);
1085
1086 writer
1087 .create_element("element")
1088 .new_line()
1089 .new_line()
1090 .write_empty()
1091 .expect("write tag failed");
1092
1093 writer
1094 .create_element("element")
1095 .with_attribute(("first", "1"))
1096 .new_line()
1097 .new_line()
1098 .with_attribute(("second", "2"))
1099 .write_empty()
1100 .expect("write tag failed");
1101
1102 assert_eq!(
1103 std::str::from_utf8(&buffer).unwrap(),
1104 r#"<element/><element first="1" second="2"/>"#
1105 );
1106 }
1107
1108 #[test]
1109 fn long_element_name() {
1110 let mut buffer = Vec::new();
1111 let mut writer = Writer::new_with_indent(&mut buffer, b't', 1);
1112
1113 writer
1114 .create_element(String::from("x").repeat(128).as_str())
1115 .with_attribute(("first", "1"))
1116 .new_line()
1117 .with_attribute(("second", "2"))
1118 .write_empty()
1119 .expect("Problem with indentation reference");
1120 }
1121 }
1122
1123 mod in_attributes_multi {
1124 use super::*;
1125 use pretty_assertions::assert_eq;
1126
1127 #[test]
1128 fn newline_first() {
1129 let mut buffer = Vec::new();
1130 let mut writer = Writer::new_with_indent(&mut buffer, b'_', 1);
1131
1132 writer
1133 .create_element("element")
1134 .new_line()
1135 .with_attributes([("first", "1"), ("second", "2")])
1136 .new_line()
1137 .with_attributes([("third", "3"), ("fourth", "4")])
1138 .write_empty()
1139 .expect("write tag failed");
1140
1141 assert_eq!(
1142 std::str::from_utf8(&buffer).unwrap(),
1143 "<element\
1144 \n_first=\"1\" second=\"2\"\
1145 \n_third=\"3\" fourth=\"4\"/>"
1146 );
1147 }
1148
1149 #[test]
1150 fn newline_inside() {
1151 let mut buffer = Vec::new();
1152 let mut writer = Writer::new_with_indent(&mut buffer, b'_', 1);
1153
1154 writer
1155 .create_element("element")
1156 .with_attributes([("first", "1"), ("second", "2")])
1157 .new_line()
1158 .with_attributes([("third", "3"), ("fourth", "4")])
1159 .write_empty()
1160 .expect("write tag failed");
1161
1162 assert_eq!(
1163 std::str::from_utf8(&buffer).unwrap(),
1164 r#"<element first="1" second="2"
1165 third="3" fourth="4"/>"#
1166 );
1167 }
1168
1169 #[test]
1170 fn newline_last() {
1171 let mut buffer = Vec::new();
1172 let mut writer = Writer::new_with_indent(&mut buffer, b'_', 1);
1173
1174 writer
1175 .create_element("element")
1176 .new_line()
1177 .with_attributes([("first", "1"), ("second", "2")])
1178 .new_line()
1179 .with_attributes([("third", "3"), ("fourth", "4")])
1180 .new_line()
1181 .write_empty()
1182 .expect("write tag failed");
1183
1184 writer
1185 .create_element("element")
1186 .with_attributes([("first", "1"), ("second", "2")])
1187 .new_line()
1188 .with_attributes([("third", "3"), ("fourth", "4")])
1189 .new_line()
1190 .write_empty()
1191 .expect("write tag failed");
1192
1193 assert_eq!(
1194 std::str::from_utf8(&buffer).unwrap(),
1195 "<element\
1196 \n_first=\"1\" second=\"2\"\
1197 \n_third=\"3\" fourth=\"4\"\
1198 \n/>\
1199 \n<element first=\"1\" second=\"2\"\
1200 \n third=\"3\" fourth=\"4\"\
1201 \n/>"
1202 );
1203 }
1204 }
1205}