1use crate::error::{Error, Result};
34use crate::escape::escape;
35use serde::ser::{self, Serialize};
36use std::io::Write;
37
38pub fn to_string<T>(value: &T) -> Result<String>
61where
62 T: Serialize + ?Sized,
63{
64 let mut serializer = Serializer::new();
65 value.serialize(&mut serializer)?;
66 Ok(serializer.into_string())
67}
68
69pub fn to_string_with_root<T>(value: &T, root: &str) -> Result<String>
71where
72 T: Serialize + ?Sized,
73{
74 let mut serializer = Serializer::with_root(root);
75 value.serialize(&mut serializer)?;
76 Ok(serializer.into_string())
77}
78
79pub fn to_vec<T>(value: &T) -> Result<Vec<u8>>
81where
82 T: Serialize + ?Sized,
83{
84 Ok(to_string(value)?.into_bytes())
85}
86
87pub fn to_writer<W, T>(writer: W, value: &T) -> Result<()>
89where
90 W: Write,
91 T: Serialize + ?Sized,
92{
93 let xml = to_string(value)?;
94 let mut writer = writer;
95 writer.write_all(xml.as_bytes())?;
96 Ok(())
97}
98
99pub struct Serializer {
101 output: String,
102 root: Option<String>,
104 current_element: Option<String>,
106 element_stack: Vec<String>,
108 is_key: bool,
110 current_key: Option<String>,
112 include_declaration: bool,
114 indent_level: usize,
116 indent_str: Option<String>,
118}
119
120impl Serializer {
121 pub fn new() -> Self {
123 Self {
124 output: String::new(),
125 root: None,
126 current_element: None,
127 element_stack: Vec::new(),
128 is_key: false,
129 current_key: None,
130 include_declaration: false,
131 indent_level: 0,
132 indent_str: None,
133 }
134 }
135
136 pub fn with_root(root: &str) -> Self {
138 Self {
139 root: Some(root.to_string()),
140 ..Self::new()
141 }
142 }
143
144 pub fn with_indent(mut self, indent: &str) -> Self {
146 self.indent_str = Some(indent.to_string());
147 self
148 }
149
150 pub fn with_declaration(mut self) -> Self {
152 self.include_declaration = true;
153 self
154 }
155
156 pub fn into_string(self) -> String {
158 self.output
159 }
160
161 fn write_start_tag(&mut self, name: &str) {
163 self.write_indent();
164 self.output.push('<');
165 self.output.push_str(name);
166 self.output.push('>');
167 self.element_stack.push(name.to_string());
168 self.indent_level += 1;
169 }
170
171 fn write_start_tag_with_attrs(&mut self, name: &str, attrs: &[(String, String)]) {
173 self.write_indent();
174 self.output.push('<');
175 self.output.push_str(name);
176 for (attr_name, attr_value) in attrs {
177 self.output.push(' ');
178 self.output.push_str(attr_name);
179 self.output.push_str("=\"");
180 self.output.push_str(&escape(attr_value));
181 self.output.push('"');
182 }
183 self.output.push('>');
184 self.element_stack.push(name.to_string());
185 self.indent_level += 1;
186 }
187
188 fn write_end_tag(&mut self) {
190 self.indent_level = self.indent_level.saturating_sub(1);
191
192 if let Some(name) = self.element_stack.pop() {
193 self.write_indent();
194 self.output.push_str("</");
195 self.output.push_str(&name);
196 self.output.push('>');
197 }
198 }
199
200 fn write_empty_element(&mut self, name: &str) {
202 self.write_indent();
203 self.output.push('<');
204 self.output.push_str(name);
205 self.output.push_str("/>");
206 }
207
208 fn write_empty_element_with_attrs(&mut self, name: &str, attrs: &[(String, String)]) {
210 self.write_indent();
211 self.output.push('<');
212 self.output.push_str(name);
213 for (attr_name, attr_value) in attrs {
214 self.output.push(' ');
215 self.output.push_str(attr_name);
216 self.output.push_str("=\"");
217 self.output.push_str(&escape(attr_value));
218 self.output.push('"');
219 }
220 self.output.push_str("/>");
221 }
222
223 fn write_element(&mut self, name: &str, content: &str) {
225 self.write_indent();
226 self.output.push('<');
227 self.output.push_str(name);
228 self.output.push('>');
229 self.output.push_str(&escape(content));
230 self.output.push_str("</");
231 self.output.push_str(name);
232 self.output.push('>');
233 }
234
235 fn write_text(&mut self, content: &str) {
237 self.output.push_str(&escape(content));
238 }
239
240 fn write_indent(&mut self) {
242 if let Some(ref indent) = self.indent_str {
243 if !self.output.is_empty() && !self.output.ends_with('\n') {
244 self.output.push('\n');
245 }
246 for _ in 0..self.indent_level.saturating_sub(1) {
247 self.output.push_str(indent);
248 }
249 }
250 }
251
252 fn get_element_name(&self, fallback: &str) -> String {
254 self.current_key
255 .clone()
256 .or_else(|| self.current_element.clone())
257 .or_else(|| self.root.clone())
258 .unwrap_or_else(|| fallback.to_string())
259 }
260}
261
262impl Default for Serializer {
263 fn default() -> Self {
264 Self::new()
265 }
266}
267
268impl<'a> ser::Serializer for &'a mut Serializer {
269 type Ok = ();
270 type Error = Error;
271
272 type SerializeSeq = SeqSerializer<'a>;
273 type SerializeTuple = SeqSerializer<'a>;
274 type SerializeTupleStruct = SeqSerializer<'a>;
275 type SerializeTupleVariant = SeqSerializer<'a>;
276 type SerializeMap = MapSerializer<'a>;
277 type SerializeStruct = StructSerializer<'a>;
278 type SerializeStructVariant = StructSerializer<'a>;
279
280 fn serialize_bool(self, v: bool) -> Result<()> {
281 let text = if v { "true" } else { "false" };
282 if let Some(ref key) = self.current_key.take() {
283 self.write_element(key, text);
284 } else {
285 self.write_text(text);
286 }
287 Ok(())
288 }
289
290 fn serialize_i8(self, v: i8) -> Result<()> {
291 self.serialize_i64(v as i64)
292 }
293
294 fn serialize_i16(self, v: i16) -> Result<()> {
295 self.serialize_i64(v as i64)
296 }
297
298 fn serialize_i32(self, v: i32) -> Result<()> {
299 self.serialize_i64(v as i64)
300 }
301
302 fn serialize_i64(self, v: i64) -> Result<()> {
303 let mut buffer = itoa::Buffer::new();
304 let text = buffer.format(v);
305 if let Some(ref key) = self.current_key.take() {
306 self.write_element(key, text);
307 } else {
308 self.write_text(text);
309 }
310 Ok(())
311 }
312
313 fn serialize_u8(self, v: u8) -> Result<()> {
314 self.serialize_u64(v as u64)
315 }
316
317 fn serialize_u16(self, v: u16) -> Result<()> {
318 self.serialize_u64(v as u64)
319 }
320
321 fn serialize_u32(self, v: u32) -> Result<()> {
322 self.serialize_u64(v as u64)
323 }
324
325 fn serialize_u64(self, v: u64) -> Result<()> {
326 let mut buffer = itoa::Buffer::new();
327 let text = buffer.format(v);
328 if let Some(ref key) = self.current_key.take() {
329 self.write_element(key, text);
330 } else {
331 self.write_text(text);
332 }
333 Ok(())
334 }
335
336 fn serialize_f32(self, v: f32) -> Result<()> {
337 self.serialize_f64(v as f64)
338 }
339
340 fn serialize_f64(self, v: f64) -> Result<()> {
341 let mut buffer = ryu::Buffer::new();
342 let text = buffer.format(v);
343 if let Some(ref key) = self.current_key.take() {
344 self.write_element(key, text);
345 } else {
346 self.write_text(text);
347 }
348 Ok(())
349 }
350
351 fn serialize_char(self, v: char) -> Result<()> {
352 let mut buf = [0u8; 4];
353 let text = v.encode_utf8(&mut buf);
354 if let Some(ref key) = self.current_key.take() {
355 self.write_element(key, text);
356 } else {
357 self.write_text(text);
358 }
359 Ok(())
360 }
361
362 fn serialize_str(self, v: &str) -> Result<()> {
363 if self.is_key {
364 self.current_key = Some(v.to_string());
365 self.is_key = false;
366 } else if let Some(ref key) = self.current_key.take() {
367 self.write_element(key, v);
368 } else {
369 self.write_text(v);
370 }
371 Ok(())
372 }
373
374 fn serialize_bytes(self, v: &[u8]) -> Result<()> {
375 use std::fmt::Write;
377 let mut encoded = String::new();
378 for byte in v {
379 write!(&mut encoded, "{:02x}", byte).unwrap();
380 }
381 if let Some(ref key) = self.current_key.take() {
382 self.write_element(key, &encoded);
383 } else {
384 self.write_text(&encoded);
385 }
386 Ok(())
387 }
388
389 fn serialize_none(self) -> Result<()> {
390 self.current_key = None;
392 Ok(())
393 }
394
395 fn serialize_some<T>(self, value: &T) -> Result<()>
396 where
397 T: Serialize + ?Sized,
398 {
399 value.serialize(self)
400 }
401
402 fn serialize_unit(self) -> Result<()> {
403 if let Some(ref key) = self.current_key.take() {
404 self.write_empty_element(key);
405 }
406 Ok(())
407 }
408
409 fn serialize_unit_struct(self, name: &'static str) -> Result<()> {
410 let elem_name = self.get_element_name(name);
411 self.write_empty_element(&elem_name);
412 Ok(())
413 }
414
415 fn serialize_unit_variant(
416 self,
417 _name: &'static str,
418 _variant_index: u32,
419 variant: &'static str,
420 ) -> Result<()> {
421 if let Some(ref key) = self.current_key.take() {
422 self.write_element(key, variant);
423 } else {
424 self.write_empty_element(variant);
425 }
426 Ok(())
427 }
428
429 fn serialize_newtype_struct<T>(self, name: &'static str, value: &T) -> Result<()>
430 where
431 T: Serialize + ?Sized,
432 {
433 self.current_element = Some(name.to_string());
434 value.serialize(self)
435 }
436
437 fn serialize_newtype_variant<T>(
438 self,
439 _name: &'static str,
440 _variant_index: u32,
441 variant: &'static str,
442 value: &T,
443 ) -> Result<()>
444 where
445 T: Serialize + ?Sized,
446 {
447 self.write_start_tag(variant);
448 value.serialize(&mut *self)?;
449 self.write_end_tag();
450 Ok(())
451 }
452
453 fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
454 let element_name = self.current_key.take().unwrap_or_else(|| "item".to_string());
455 Ok(SeqSerializer {
456 ser: self,
457 element_name,
458 })
459 }
460
461 fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple> {
462 self.serialize_seq(Some(len))
463 }
464
465 fn serialize_tuple_struct(
466 self,
467 name: &'static str,
468 _len: usize,
469 ) -> Result<Self::SerializeTupleStruct> {
470 self.write_start_tag(name);
471 Ok(SeqSerializer {
472 ser: self,
473 element_name: "item".to_string(),
474 })
475 }
476
477 fn serialize_tuple_variant(
478 self,
479 _name: &'static str,
480 _variant_index: u32,
481 variant: &'static str,
482 _len: usize,
483 ) -> Result<Self::SerializeTupleVariant> {
484 self.write_start_tag(variant);
485 Ok(SeqSerializer {
486 ser: self,
487 element_name: "item".to_string(),
488 })
489 }
490
491 fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
492 let name = self.current_key.take()
493 .or_else(|| self.root.clone())
494 .unwrap_or_else(|| "map".to_string());
495 self.write_start_tag(&name);
496 Ok(MapSerializer { ser: self })
497 }
498
499 fn serialize_struct(self, name: &'static str, _len: usize) -> Result<Self::SerializeStruct> {
500 let elem_name = self.current_key.take().unwrap_or_else(|| name.to_string());
501 Ok(StructSerializer {
503 ser: self,
504 elem_name,
505 attrs: Vec::new(),
506 children: Vec::new(),
507 text_content: None,
508 started: false,
509 })
510 }
511
512 fn serialize_struct_variant(
513 self,
514 _name: &'static str,
515 _variant_index: u32,
516 variant: &'static str,
517 _len: usize,
518 ) -> Result<Self::SerializeStructVariant> {
519 Ok(StructSerializer {
520 ser: self,
521 elem_name: variant.to_string(),
522 attrs: Vec::new(),
523 children: Vec::new(),
524 text_content: None,
525 started: false,
526 })
527 }
528}
529
530struct AttrValueSerializer {
532 output: String,
533}
534
535impl AttrValueSerializer {
536 fn new() -> Self {
537 Self { output: String::new() }
538 }
539
540 fn into_string(self) -> String {
541 self.output
542 }
543}
544
545impl ser::Serializer for &mut AttrValueSerializer {
546 type Ok = ();
547 type Error = Error;
548
549 type SerializeSeq = ser::Impossible<(), Error>;
550 type SerializeTuple = ser::Impossible<(), Error>;
551 type SerializeTupleStruct = ser::Impossible<(), Error>;
552 type SerializeTupleVariant = ser::Impossible<(), Error>;
553 type SerializeMap = ser::Impossible<(), Error>;
554 type SerializeStruct = ser::Impossible<(), Error>;
555 type SerializeStructVariant = ser::Impossible<(), Error>;
556
557 fn serialize_bool(self, v: bool) -> Result<()> {
558 self.output.push_str(if v { "true" } else { "false" });
559 Ok(())
560 }
561
562 fn serialize_i8(self, v: i8) -> Result<()> { self.serialize_i64(v as i64) }
563 fn serialize_i16(self, v: i16) -> Result<()> { self.serialize_i64(v as i64) }
564 fn serialize_i32(self, v: i32) -> Result<()> { self.serialize_i64(v as i64) }
565 fn serialize_i64(self, v: i64) -> Result<()> {
566 let mut buffer = itoa::Buffer::new();
567 self.output.push_str(buffer.format(v));
568 Ok(())
569 }
570
571 fn serialize_u8(self, v: u8) -> Result<()> { self.serialize_u64(v as u64) }
572 fn serialize_u16(self, v: u16) -> Result<()> { self.serialize_u64(v as u64) }
573 fn serialize_u32(self, v: u32) -> Result<()> { self.serialize_u64(v as u64) }
574 fn serialize_u64(self, v: u64) -> Result<()> {
575 let mut buffer = itoa::Buffer::new();
576 self.output.push_str(buffer.format(v));
577 Ok(())
578 }
579
580 fn serialize_f32(self, v: f32) -> Result<()> { self.serialize_f64(v as f64) }
581 fn serialize_f64(self, v: f64) -> Result<()> {
582 let mut buffer = ryu::Buffer::new();
583 self.output.push_str(buffer.format(v));
584 Ok(())
585 }
586
587 fn serialize_char(self, v: char) -> Result<()> {
588 self.output.push(v);
589 Ok(())
590 }
591
592 fn serialize_str(self, v: &str) -> Result<()> {
593 self.output.push_str(v);
595 Ok(())
596 }
597
598 fn serialize_bytes(self, _v: &[u8]) -> Result<()> {
599 Err(Error::unsupported("bytes in attribute"))
600 }
601
602 fn serialize_none(self) -> Result<()> { Ok(()) }
603 fn serialize_some<T: ?Sized + Serialize>(self, v: &T) -> Result<()> { v.serialize(self) }
604 fn serialize_unit(self) -> Result<()> { Ok(()) }
605 fn serialize_unit_struct(self, _name: &'static str) -> Result<()> { Ok(()) }
606 fn serialize_unit_variant(self, _name: &'static str, _idx: u32, variant: &'static str) -> Result<()> {
607 self.output.push_str(variant);
608 Ok(())
609 }
610 fn serialize_newtype_struct<T: ?Sized + Serialize>(self, _name: &'static str, v: &T) -> Result<()> {
611 v.serialize(self)
612 }
613 fn serialize_newtype_variant<T: ?Sized + Serialize>(self, _name: &'static str, _idx: u32, _variant: &'static str, v: &T) -> Result<()> {
614 v.serialize(self)
615 }
616
617 fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
618 Err(Error::unsupported("sequence in attribute"))
619 }
620 fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> {
621 Err(Error::unsupported("tuple in attribute"))
622 }
623 fn serialize_tuple_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeTupleStruct> {
624 Err(Error::unsupported("tuple struct in attribute"))
625 }
626 fn serialize_tuple_variant(self, _name: &'static str, _idx: u32, _variant: &'static str, _len: usize) -> Result<Self::SerializeTupleVariant> {
627 Err(Error::unsupported("tuple variant in attribute"))
628 }
629 fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
630 Err(Error::unsupported("map in attribute"))
631 }
632 fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct> {
633 Err(Error::unsupported("struct in attribute"))
634 }
635 fn serialize_struct_variant(self, _name: &'static str, _idx: u32, _variant: &'static str, _len: usize) -> Result<Self::SerializeStructVariant> {
636 Err(Error::unsupported("struct variant in attribute"))
637 }
638}
639
640pub struct SeqSerializer<'a> {
642 ser: &'a mut Serializer,
643 element_name: String,
644}
645
646impl<'a> ser::SerializeSeq for SeqSerializer<'a> {
647 type Ok = ();
648 type Error = Error;
649
650 fn serialize_element<T>(&mut self, value: &T) -> Result<()>
651 where
652 T: Serialize + ?Sized,
653 {
654 self.ser.current_key = Some(self.element_name.clone());
655 value.serialize(&mut *self.ser)
656 }
657
658 fn end(self) -> Result<()> {
659 Ok(())
660 }
661}
662
663impl<'a> ser::SerializeTuple for SeqSerializer<'a> {
664 type Ok = ();
665 type Error = Error;
666
667 fn serialize_element<T>(&mut self, value: &T) -> Result<()>
668 where
669 T: Serialize + ?Sized,
670 {
671 ser::SerializeSeq::serialize_element(self, value)
672 }
673
674 fn end(self) -> Result<()> {
675 ser::SerializeSeq::end(self)
676 }
677}
678
679impl<'a> ser::SerializeTupleStruct for SeqSerializer<'a> {
680 type Ok = ();
681 type Error = Error;
682
683 fn serialize_field<T>(&mut self, value: &T) -> Result<()>
684 where
685 T: Serialize + ?Sized,
686 {
687 self.ser.current_key = Some(self.element_name.clone());
688 value.serialize(&mut *self.ser)
689 }
690
691 fn end(self) -> Result<()> {
692 self.ser.write_end_tag();
693 Ok(())
694 }
695}
696
697impl<'a> ser::SerializeTupleVariant for SeqSerializer<'a> {
698 type Ok = ();
699 type Error = Error;
700
701 fn serialize_field<T>(&mut self, value: &T) -> Result<()>
702 where
703 T: Serialize + ?Sized,
704 {
705 self.ser.current_key = Some(self.element_name.clone());
706 value.serialize(&mut *self.ser)
707 }
708
709 fn end(self) -> Result<()> {
710 self.ser.write_end_tag();
711 Ok(())
712 }
713}
714
715pub struct MapSerializer<'a> {
717 ser: &'a mut Serializer,
718}
719
720impl<'a> ser::SerializeMap for MapSerializer<'a> {
721 type Ok = ();
722 type Error = Error;
723
724 fn serialize_key<T>(&mut self, key: &T) -> Result<()>
725 where
726 T: Serialize + ?Sized,
727 {
728 self.ser.is_key = true;
729 key.serialize(&mut *self.ser)
730 }
731
732 fn serialize_value<T>(&mut self, value: &T) -> Result<()>
733 where
734 T: Serialize + ?Sized,
735 {
736 value.serialize(&mut *self.ser)
737 }
738
739 fn end(self) -> Result<()> {
740 self.ser.write_end_tag();
741 Ok(())
742 }
743}
744
745pub struct StructSerializer<'a> {
747 ser: &'a mut Serializer,
748 elem_name: String,
749 attrs: Vec<(String, String)>,
750 children: Vec<String>,
751 text_content: Option<String>,
752 started: bool,
753}
754
755impl<'a> StructSerializer<'a> {
756 fn ensure_started(&mut self) {
757 if !self.started {
758 self.ser.write_start_tag_with_attrs(&self.elem_name, &self.attrs);
759 for child in &self.children {
761 self.ser.output.push_str(child);
762 }
763 self.children.clear();
764 self.started = true;
765 }
766 }
767}
768
769impl<'a> ser::SerializeStruct for StructSerializer<'a> {
770 type Ok = ();
771 type Error = Error;
772
773 fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
774 where
775 T: Serialize + ?Sized,
776 {
777 if let Some(attr_name) = key.strip_prefix('@') {
779 let mut attr_ser = AttrValueSerializer::new();
781 value.serialize(&mut attr_ser)?;
782 let attr_value = attr_ser.into_string();
783 self.attrs.push((attr_name.to_string(), attr_value));
784 return Ok(());
785 }
786
787 if key == "$value" || key == "$text" {
789 let mut text_ser = Serializer::new();
791 value.serialize(&mut text_ser)?;
792 self.text_content = Some(text_ser.into_string());
793 return Ok(());
794 }
795
796 self.ensure_started();
798 self.ser.current_key = Some(key.to_string());
799 value.serialize(&mut *self.ser)
800 }
801
802 fn end(self) -> Result<()> {
803 if self.started {
804 if let Some(text) = self.text_content {
806 self.ser.output.push_str(&text);
807 }
808 self.ser.write_end_tag();
809 } else if self.attrs.is_empty() && self.text_content.is_none() {
810 self.ser.write_empty_element(&self.elem_name);
812 } else if let Some(text) = self.text_content {
813 self.ser.write_start_tag_with_attrs(&self.elem_name, &self.attrs);
815 self.ser.output.push_str(&text);
816 self.ser.write_end_tag();
817 } else {
818 self.ser.write_empty_element_with_attrs(&self.elem_name, &self.attrs);
820 }
821 Ok(())
822 }
823}
824
825impl<'a> ser::SerializeStructVariant for StructSerializer<'a> {
826 type Ok = ();
827 type Error = Error;
828
829 fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
830 where
831 T: Serialize + ?Sized,
832 {
833 ser::SerializeStruct::serialize_field(self, key, value)
834 }
835
836 fn end(self) -> Result<()> {
837 ser::SerializeStruct::end(self)
838 }
839}
840
841#[cfg(test)]
842mod tests {
843 use super::*;
844 use serde::Serialize;
845
846 #[test]
847 fn test_serialize_simple_struct() {
848 #[derive(Serialize)]
849 struct Person {
850 name: String,
851 age: u32,
852 }
853
854 let person = Person {
855 name: "Alice".to_string(),
856 age: 30,
857 };
858
859 let xml = to_string(&person).unwrap();
860 assert!(xml.contains("<Person>"));
861 assert!(xml.contains("<name>Alice</name>"));
862 assert!(xml.contains("<age>30</age>"));
863 assert!(xml.contains("</Person>"));
864 }
865
866 #[test]
867 fn test_serialize_with_attributes() {
868 #[derive(Serialize)]
869 struct Element {
870 #[serde(rename = "@id")]
871 id: String,
872 #[serde(rename = "@class")]
873 class: String,
874 content: String,
875 }
876
877 let elem = Element {
878 id: "main".to_string(),
879 class: "container".to_string(),
880 content: "Hello".to_string(),
881 };
882
883 let xml = to_string(&elem).unwrap();
884 assert!(xml.contains(r#"id="main""#));
885 assert!(xml.contains(r#"class="container""#));
886 assert!(xml.contains("<content>Hello</content>"));
887 }
888
889 #[test]
890 fn test_serialize_attributes_only() {
891 #[derive(Serialize)]
892 struct EmptyElement {
893 #[serde(rename = "@id")]
894 id: String,
895 #[serde(rename = "@disabled")]
896 disabled: bool,
897 }
898
899 let elem = EmptyElement {
900 id: "btn".to_string(),
901 disabled: true,
902 };
903
904 let xml = to_string(&elem).unwrap();
905 assert!(xml.contains(r#"id="btn""#));
906 assert!(xml.contains(r#"disabled="true""#));
907 assert!(xml.contains("/>") || xml.contains("</EmptyElement>"));
908 }
909
910 #[test]
911 fn test_serialize_text_content() {
912 #[derive(Serialize)]
913 struct TextElement {
914 #[serde(rename = "@id")]
915 id: String,
916 #[serde(rename = "$value")]
917 text: String,
918 }
919
920 let elem = TextElement {
921 id: "para".to_string(),
922 text: "Hello World".to_string(),
923 };
924
925 let xml = to_string(&elem).unwrap();
926 assert!(xml.contains(r#"id="para""#));
927 assert!(xml.contains("Hello World"));
928 }
929
930 #[test]
931 fn test_serialize_nested_struct() {
932 #[derive(Serialize)]
933 struct Address {
934 city: String,
935 country: String,
936 }
937
938 #[derive(Serialize)]
939 struct Person {
940 name: String,
941 address: Address,
942 }
943
944 let person = Person {
945 name: "Bob".to_string(),
946 address: Address {
947 city: "New York".to_string(),
948 country: "USA".to_string(),
949 },
950 };
951
952 let xml = to_string(&person).unwrap();
953 assert!(xml.contains("<address>"));
954 assert!(xml.contains("<city>New York</city>"));
955 assert!(xml.contains("</address>"));
956 }
957
958 #[test]
959 fn test_serialize_optional() {
960 #[derive(Serialize)]
961 struct Config {
962 name: String,
963 value: Option<String>,
964 }
965
966 let with_value = Config {
967 name: "test".to_string(),
968 value: Some("val".to_string()),
969 };
970 let xml = to_string(&with_value).unwrap();
971 assert!(xml.contains("<value>val</value>"));
972
973 let without_value = Config {
974 name: "test".to_string(),
975 value: None,
976 };
977 let xml = to_string(&without_value).unwrap();
978 assert!(!xml.contains("<value>"));
979 }
980
981 #[test]
982 fn test_serialize_vector() {
983 #[derive(Serialize)]
984 struct Items {
985 items: Vec<String>,
986 }
987
988 let items = Items {
989 items: vec!["one".to_string(), "two".to_string(), "three".to_string()],
990 };
991
992 let xml = to_string(&items).unwrap();
993 assert!(xml.contains("<items>one</items>"));
994 assert!(xml.contains("<items>two</items>"));
995 assert!(xml.contains("<items>three</items>"));
996 }
997
998 #[test]
999 fn test_serialize_escaped_content() {
1000 #[derive(Serialize)]
1001 struct Data {
1002 content: String,
1003 }
1004
1005 let data = Data {
1006 content: "<hello> & \"world\"".to_string(),
1007 };
1008
1009 let xml = to_string(&data).unwrap();
1010 assert!(xml.contains("<hello>"));
1011 assert!(xml.contains("&"));
1012 assert!(xml.contains("""));
1013 }
1014
1015 #[test]
1016 fn test_serialize_escaped_attribute() {
1017 #[derive(Serialize)]
1018 struct Element {
1019 #[serde(rename = "@title")]
1020 title: String,
1021 }
1022
1023 let elem = Element {
1024 title: "Hello \"World\" & <Friends>".to_string(),
1025 };
1026
1027 let xml = to_string(&elem).unwrap();
1028 assert!(xml.contains("""));
1029 assert!(xml.contains("&"));
1030 assert!(xml.contains("<"));
1031 }
1032
1033 #[test]
1034 fn test_serialize_bool() {
1035 #[derive(Serialize)]
1036 struct Flags {
1037 enabled: bool,
1038 active: bool,
1039 }
1040
1041 let flags = Flags {
1042 enabled: true,
1043 active: false,
1044 };
1045
1046 let xml = to_string(&flags).unwrap();
1047 assert!(xml.contains("<enabled>true</enabled>"));
1048 assert!(xml.contains("<active>false</active>"));
1049 }
1050
1051 #[test]
1052 fn test_serialize_numbers() {
1053 #[derive(Serialize)]
1054 struct Numbers {
1055 i: i32,
1056 u: u64,
1057 f: f64,
1058 }
1059
1060 let nums = Numbers {
1061 i: -42,
1062 u: 100,
1063 f: 1.234,
1064 };
1065
1066 let xml = to_string(&nums).unwrap();
1067 assert!(xml.contains("<i>-42</i>"));
1068 assert!(xml.contains("<u>100</u>"));
1069 assert!(xml.contains("<f>1.234</f>"));
1070 }
1071
1072 #[test]
1073 fn test_serialize_enum() {
1074 #[derive(Serialize)]
1075 enum Status {
1076 Active,
1077 #[allow(dead_code)]
1078 Inactive,
1079 #[allow(dead_code)]
1080 Pending,
1081 }
1082
1083 #[derive(Serialize)]
1084 struct Item {
1085 status: Status,
1086 }
1087
1088 let item = Item {
1089 status: Status::Active,
1090 };
1091
1092 let xml = to_string(&item).unwrap();
1093 assert!(xml.contains("<status>Active</status>") || xml.contains("<Active/>"));
1094 }
1095
1096 #[test]
1097 fn test_serialize_unit_struct() {
1098 #[derive(Serialize)]
1099 struct Empty;
1100
1101 let xml = to_string(&Empty).unwrap();
1102 assert!(xml.contains("<Empty/>"));
1103 }
1104
1105 #[test]
1106 fn test_serialize_char() {
1107 #[derive(Serialize)]
1108 struct Data {
1109 c: char,
1110 }
1111
1112 let data = Data { c: 'A' };
1113 let xml = to_string(&data).unwrap();
1114 assert!(xml.contains("<c>A</c>"));
1115 }
1116
1117 #[test]
1118 fn test_to_vec() {
1119 #[derive(Serialize)]
1120 struct Data {
1121 value: String,
1122 }
1123
1124 let data = Data {
1125 value: "test".to_string(),
1126 };
1127
1128 let bytes = to_vec(&data).unwrap();
1129 let xml = String::from_utf8(bytes).unwrap();
1130 assert!(xml.contains("<value>test</value>"));
1131 }
1132
1133 #[test]
1134 fn test_to_writer() {
1135 #[derive(Serialize)]
1136 struct Data {
1137 value: String,
1138 }
1139
1140 let data = Data {
1141 value: "test".to_string(),
1142 };
1143
1144 let mut buffer = Vec::new();
1145 to_writer(&mut buffer, &data).unwrap();
1146 let xml = String::from_utf8(buffer).unwrap();
1147 assert!(xml.contains("<value>test</value>"));
1148 }
1149
1150 #[test]
1151 fn test_with_root() {
1152 #[derive(Serialize)]
1153 struct Data {
1154 value: String,
1155 }
1156
1157 let data = Data {
1158 value: "test".to_string(),
1159 };
1160
1161 let xml = to_string_with_root(&data, "root").unwrap();
1162 assert!(xml.contains("<value>test</value>"));
1164 }
1165
1166 #[test]
1167 fn test_complex_with_attributes() {
1168 #[derive(Serialize)]
1169 struct Item {
1170 #[serde(rename = "@id")]
1171 id: u32,
1172 #[serde(rename = "@class")]
1173 class: String,
1174 name: String,
1175 value: i32,
1176 }
1177
1178 #[derive(Serialize)]
1179 struct Container {
1180 #[serde(rename = "@version")]
1181 version: String,
1182 item: Vec<Item>,
1183 }
1184
1185 let container = Container {
1186 version: "1.0".to_string(),
1187 item: vec![
1188 Item {
1189 id: 1,
1190 class: "primary".to_string(),
1191 name: "First".to_string(),
1192 value: 100,
1193 },
1194 Item {
1195 id: 2,
1196 class: "secondary".to_string(),
1197 name: "Second".to_string(),
1198 value: 200,
1199 },
1200 ],
1201 };
1202
1203 let xml = to_string(&container).unwrap();
1204 assert!(xml.contains(r#"version="1.0""#));
1205 assert!(xml.contains(r#"id="1""#));
1206 assert!(xml.contains(r#"class="primary""#));
1207 assert!(xml.contains("<name>First</name>"));
1208 }
1209}