@@ -10,6 +10,10 @@ use crate::events::{attributes::Attribute, BytesCData, BytesStart, BytesText, Ev
10
10
mod async_tokio;
11
11
12
12
/// XML writer. Writes XML [`Event`]s to a [`std::io::Write`] or [`tokio::io::AsyncWrite`] implementor.
13
+ #[ cfg( feature = "serialize" ) ]
14
+ use { crate :: de:: DeError , serde:: Serialize } ;
15
+
16
+ /// XML writer. Writes XML [`Event`]s to a [`std::io::Write`] implementor.
13
17
///
14
18
/// # Examples
15
19
///
@@ -75,7 +79,7 @@ impl<W> Writer<W> {
75
79
pub fn new_with_indent ( inner : W , indent_char : u8 , indent_size : usize ) -> Writer < W > {
76
80
Writer {
77
81
writer : inner,
78
- indent : Some ( Indentation :: new ( indent_char, indent_size) ) ,
82
+ indent : Some ( Indentation :: new ( indent_char, indent_size, 0 ) ) ,
79
83
}
80
84
}
81
85
@@ -340,6 +344,49 @@ impl<'a, W: Write> ElementWriter<'a, W> {
340
344
. write_event ( Event :: End ( self . start_tag . to_end ( ) ) ) ?;
341
345
Ok ( self . writer )
342
346
}
347
+
348
+ /// Serialize an arbitrary value inside the current element
349
+ #[ cfg( feature = "serialize" ) ]
350
+ pub fn write_serializable_content < T : Serialize > (
351
+ self ,
352
+ content : T ,
353
+ ) -> std:: result:: Result < & ' a mut Writer < W > , DeError > {
354
+ use crate :: se:: Serializer ;
355
+
356
+ self . writer
357
+ . write_event ( Event :: Start ( self . start_tag . borrow ( ) ) ) ?;
358
+ self . writer . write_indent ( ) ?;
359
+
360
+ let indent = self . writer . indent . clone ( ) ;
361
+ let mut serializer = Serializer :: new ( ToFmtWrite ( self . writer . inner ( ) ) ) ;
362
+
363
+ if let Some ( indent) = indent {
364
+ serializer. indent_with_len (
365
+ indent. indent_char as char ,
366
+ indent. indent_size ,
367
+ indent. indents_len ,
368
+ ) ;
369
+ }
370
+
371
+ content. serialize ( serializer) ?;
372
+
373
+ self . writer
374
+ . write_event ( Event :: End ( self . start_tag . to_end ( ) ) ) ?;
375
+ Ok ( self . writer )
376
+ }
377
+ }
378
+
379
+ #[ cfg( feature = "serialize" ) ]
380
+ struct ToFmtWrite < T > ( pub T ) ;
381
+
382
+ #[ cfg( feature = "serialize" ) ]
383
+ impl < T > std:: fmt:: Write for ToFmtWrite < T >
384
+ where
385
+ T : std:: io:: Write ,
386
+ {
387
+ fn write_str ( & mut self , s : & str ) -> std:: fmt:: Result {
388
+ self . 0 . write_all ( s. as_bytes ( ) ) . map_err ( |_| std:: fmt:: Error )
389
+ }
343
390
}
344
391
345
392
#[ derive( Clone ) ]
@@ -352,13 +399,13 @@ pub(crate) struct Indentation {
352
399
}
353
400
354
401
impl Indentation {
355
- pub fn new ( indent_char : u8 , indent_size : usize ) -> Self {
402
+ pub fn new ( indent_char : u8 , indent_size : usize , indents_len : usize ) -> Self {
356
403
Self {
357
404
should_line_break : false ,
358
405
indent_char,
359
406
indent_size,
360
407
indents : vec ! [ indent_char; 128 ] ,
361
- indents_len : 0 ,
408
+ indents_len,
362
409
}
363
410
}
364
411
@@ -623,4 +670,49 @@ mod indentation {
623
670
</outer>"#
624
671
) ;
625
672
}
673
+
674
+ #[ cfg( feature = "serialize" ) ]
675
+ #[ derive( Serialize ) ]
676
+ struct Foo {
677
+ bar : Bar ,
678
+ val : String ,
679
+ }
680
+
681
+ #[ cfg( feature = "serialize" ) ]
682
+ #[ derive( Serialize ) ]
683
+ struct Bar {
684
+ baz : usize ,
685
+ bat : usize ,
686
+ }
687
+
688
+ #[ cfg( feature = "serialize" ) ]
689
+ #[ test]
690
+ fn element_writer_serialize ( ) {
691
+ let mut buffer = Vec :: new ( ) ;
692
+ let mut writer = Writer :: new_with_indent ( & mut buffer, b' ' , 4 ) ;
693
+ let content = Foo {
694
+ bar : Bar { baz : 42 , bat : 43 } ,
695
+ val : "foo" . to_owned ( ) ,
696
+ } ;
697
+
698
+ writer
699
+ . create_element ( "paired" )
700
+ . with_attribute ( ( "attr1" , "value1" ) )
701
+ . with_attribute ( ( "attr2" , "value2" ) )
702
+ . write_serializable_content ( content)
703
+ . expect ( "failure" ) ;
704
+
705
+ assert_eq ! (
706
+ std:: str :: from_utf8( & buffer) . unwrap( ) ,
707
+ r#"<paired attr1="value1" attr2="value2">
708
+ <Foo>
709
+ <bar>
710
+ <baz>42</baz>
711
+ <bat>43</bat>
712
+ </bar>
713
+ <val>foo</val>
714
+ </Foo>
715
+ </paired>"#
716
+ ) ;
717
+ }
626
718
}
0 commit comments