1use std::future::Future;
2use std::result::Result as StdResult;
3
4use tokio::io::{AsyncWrite, AsyncWriteExt};
5
6use crate::errors::{Error, Result};
7use crate::events::{BytesCData, BytesPI, BytesText, Event};
8use crate::{ElementWriter, Writer};
9
10impl<W: AsyncWrite + Unpin> Writer<W> {
11 pub async fn write_event_async<'a, E: Into<Event<'a>>>(&mut self, event: E) -> Result<()> {
13 let mut next_should_line_break = true;
14 let result = match event.into() {
15 Event::Start(e) => {
16 let result = self.write_wrapped_async(b"<", &e, b">").await;
17 if let Some(i) = self.indent.as_mut() {
18 i.grow();
19 }
20 result
21 }
22 Event::End(e) => {
23 if let Some(i) = self.indent.as_mut() {
24 i.shrink();
25 }
26 self.write_wrapped_async(b"</", &e, b">").await
27 }
28 Event::Empty(e) => self.write_wrapped_async(b"<", &e, b"/>").await,
29 Event::Text(e) => {
30 next_should_line_break = false;
31 self.write_async(&e).await
32 }
33 Event::Comment(e) => self.write_wrapped_async(b"<!--", &e, b"-->").await,
34 Event::CData(e) => {
35 next_should_line_break = false;
36 self.write_async(b"<![CDATA[").await?;
37 self.write_async(&e).await?;
38 self.write_async(b"]]>").await
39 }
40 Event::Decl(e) => self.write_wrapped_async(b"<?", &e, b"?>").await,
41 Event::PI(e) => self.write_wrapped_async(b"<?", &e, b"?>").await,
42 Event::DocType(e) => self.write_wrapped_async(b"<!DOCTYPE ", &e, b">").await,
43 Event::GeneralRef(e) => self.write_wrapped_async(b"&", &e, b";").await,
44 Event::Eof => Ok(()),
45 };
46 if let Some(i) = self.indent.as_mut() {
47 i.should_line_break = next_should_line_break;
48 }
49 result
50 }
51
52 pub async fn write_indent_async(&mut self) -> Result<()> {
57 if let Some(ref i) = self.indent {
58 self.writer.write_all(b"\n").await?;
59 self.writer.write_all(i.current()).await?;
60 }
61 Ok(())
62 }
63
64 #[inline]
65 async fn write_async(&mut self, value: &[u8]) -> Result<()> {
66 self.writer.write_all(value).await.map_err(Into::into)
67 }
68
69 #[inline]
70 async fn write_wrapped_async(
71 &mut self,
72 before: &[u8],
73 value: &[u8],
74 after: &[u8],
75 ) -> Result<()> {
76 if let Some(ref i) = self.indent {
77 if i.should_line_break {
78 self.writer.write_all(b"\n").await?;
79 self.writer.write_all(i.current()).await?;
80 }
81 }
82 self.write_async(before).await?;
83 self.write_async(value).await?;
84 self.write_async(after).await?;
85 Ok(())
86 }
87}
88
89impl<'a, W: AsyncWrite + Unpin> ElementWriter<'a, W> {
90 pub async fn write_text_content_async(self, text: BytesText<'_>) -> Result<&'a mut Writer<W>> {
119 self.writer
120 .write_event_async(Event::Start(self.start_tag.borrow()))
121 .await?;
122 self.writer.write_event_async(Event::Text(text)).await?;
123 self.writer
124 .write_event_async(Event::End(self.start_tag.to_end()))
125 .await?;
126 Ok(self.writer)
127 }
128
129 pub async fn write_cdata_content_async(
158 self,
159 text: BytesCData<'_>,
160 ) -> Result<&'a mut Writer<W>> {
161 self.writer
162 .write_event_async(Event::Start(self.start_tag.borrow()))
163 .await?;
164 self.writer.write_event_async(Event::CData(text)).await?;
165 self.writer
166 .write_event_async(Event::End(self.start_tag.to_end()))
167 .await?;
168 Ok(self.writer)
169 }
170
171 pub async fn write_pi_content_async(self, text: BytesPI<'_>) -> Result<&'a mut Writer<W>> {
202 self.writer
203 .write_event_async(Event::Start(self.start_tag.borrow()))
204 .await?;
205 self.writer.write_event_async(Event::PI(text)).await?;
206 self.writer
207 .write_event_async(Event::End(self.start_tag.to_end()))
208 .await?;
209 Ok(self.writer)
210 }
211
212 pub async fn write_empty_async(self) -> Result<&'a mut Writer<W>> {
241 self.writer
242 .write_event_async(Event::Empty(self.start_tag))
243 .await?;
244 Ok(self.writer)
245 }
246
247 pub async fn write_inner_content_async<F, Fut, E>(
301 mut self,
302 closure: F,
303 ) -> StdResult<&'a mut Writer<W>, E>
304 where
305 F: FnOnce(&'a mut Writer<W>) -> Fut,
306 Fut: Future<Output = StdResult<&'a mut Writer<W>, E>>,
307 E: From<Error>,
308 {
309 self.writer
310 .write_event_async(Event::Start(self.start_tag.borrow()))
311 .await?;
312 self.writer = closure(self.writer).await?;
313 self.writer
314 .write_event_async(Event::End(self.start_tag.to_end()))
315 .await?;
316 Ok(self.writer)
317 }
318}
319
320#[cfg(test)]
321mod tests {
322 use super::*;
323 use crate::events::*;
324 use pretty_assertions::assert_eq;
325
326 macro_rules! test {
327 ($name: ident, $event: expr, $expected: expr) => {
328 #[tokio::test]
329 async fn $name() {
330 let mut buffer = Vec::new();
331 let mut writer = Writer::new(&mut buffer);
332
333 writer
334 .write_event_async($event)
335 .await
336 .expect("write event failed");
337
338 assert_eq!(std::str::from_utf8(&buffer).unwrap(), $expected,);
339 }
340 };
341 }
342
343 test!(
344 xml_header,
345 Event::Decl(BytesDecl::new("1.0", Some("UTF-8"), Some("no"))),
346 r#"<?xml version="1.0" encoding="UTF-8" standalone="no"?>"#
347 );
348
349 test!(empty_tag, Event::Empty(BytesStart::new("tag")), r#"<tag/>"#);
350
351 test!(
352 comment,
353 Event::Comment(BytesText::new("this is a comment")),
354 r#"<!--this is a comment-->"#
355 );
356
357 test!(
358 cdata,
359 Event::CData(BytesCData::new("this is a cdata")),
360 r#"<![CDATA[this is a cdata]]>"#
361 );
362
363 test!(
364 pi,
365 Event::PI(BytesPI::new("this is a processing instruction")),
366 r#"<?this is a processing instruction?>"#
367 );
368
369 test!(
370 doctype,
371 Event::DocType(BytesText::new("this is a doctype")),
372 r#"<!DOCTYPE this is a doctype>"#
373 );
374
375 #[tokio::test]
376 async fn full_tag() {
377 let mut buffer = Vec::new();
378 let mut writer = Writer::new(&mut buffer);
379
380 let start = Event::Start(BytesStart::new("tag"));
381 let text = Event::Text(BytesText::new("inner text"));
382 let end = Event::End(BytesEnd::new("tag"));
383 for i in [start, text, end] {
384 writer.write_event_async(i).await.expect("write tag failed");
385 }
386
387 assert_eq!(
388 std::str::from_utf8(&buffer).unwrap(),
389 r#"<tag>inner text</tag>"#
390 );
391 }
392}
393
394#[cfg(test)]
395mod indentation_async {
396 use super::*;
397 use crate::events::*;
398 use pretty_assertions::assert_eq;
399
400 #[tokio::test]
401 async fn self_closed() {
402 let mut buffer = Vec::new();
403 let mut writer = Writer::new_with_indent(&mut buffer, b' ', 4);
404
405 let tag = BytesStart::new("self-closed")
406 .with_attributes(vec![("attr1", "value1"), ("attr2", "value2")].into_iter());
407 writer
408 .write_event_async(Event::Empty(tag))
409 .await
410 .expect("write tag failed");
411
412 assert_eq!(
413 std::str::from_utf8(&buffer).unwrap(),
414 r#"<self-closed attr1="value1" attr2="value2"/>"#
415 );
416 }
417
418 #[tokio::test]
419 async fn empty_paired() {
420 let mut buffer = Vec::new();
421 let mut writer = Writer::new_with_indent(&mut buffer, b' ', 4);
422
423 let start = BytesStart::new("paired")
424 .with_attributes(vec![("attr1", "value1"), ("attr2", "value2")].into_iter());
425 let end = start.to_end();
426 writer
427 .write_event_async(Event::Start(start.clone()))
428 .await
429 .expect("write start tag failed");
430 writer
431 .write_event_async(Event::End(end))
432 .await
433 .expect("write end tag failed");
434
435 assert_eq!(
436 std::str::from_utf8(&buffer).unwrap(),
437 r#"<paired attr1="value1" attr2="value2">
438</paired>"#
439 );
440 }
441
442 #[tokio::test]
443 async fn paired_with_inner() {
444 let mut buffer = Vec::new();
445 let mut writer = Writer::new_with_indent(&mut buffer, b' ', 4);
446
447 let start = BytesStart::new("paired")
448 .with_attributes(vec![("attr1", "value1"), ("attr2", "value2")].into_iter());
449 let end = start.to_end();
450 let inner = BytesStart::new("inner");
451
452 writer
453 .write_event_async(Event::Start(start.clone()))
454 .await
455 .expect("write start tag failed");
456 writer
457 .write_event_async(Event::Empty(inner))
458 .await
459 .expect("write inner tag failed");
460 writer
461 .write_event_async(Event::End(end))
462 .await
463 .expect("write end tag failed");
464
465 assert_eq!(
466 std::str::from_utf8(&buffer).unwrap(),
467 r#"<paired attr1="value1" attr2="value2">
468 <inner/>
469</paired>"#
470 );
471 }
472
473 #[tokio::test]
474 async fn paired_with_text() {
475 let mut buffer = Vec::new();
476 let mut writer = Writer::new_with_indent(&mut buffer, b' ', 4);
477
478 let start = BytesStart::new("paired")
479 .with_attributes(vec![("attr1", "value1"), ("attr2", "value2")].into_iter());
480 let end = start.to_end();
481 let text = BytesText::new("text");
482
483 writer
484 .write_event_async(Event::Start(start.clone()))
485 .await
486 .expect("write start tag failed");
487 writer
488 .write_event_async(Event::Text(text))
489 .await
490 .expect("write text failed");
491 writer
492 .write_event_async(Event::End(end))
493 .await
494 .expect("write end tag failed");
495
496 assert_eq!(
497 std::str::from_utf8(&buffer).unwrap(),
498 r#"<paired attr1="value1" attr2="value2">text</paired>"#
499 );
500 }
501
502 #[tokio::test]
503 async fn mixed_content() {
504 let mut buffer = Vec::new();
505 let mut writer = Writer::new_with_indent(&mut buffer, b' ', 4);
506
507 let start = BytesStart::new("paired")
508 .with_attributes(vec![("attr1", "value1"), ("attr2", "value2")].into_iter());
509 let end = start.to_end();
510 let text = BytesText::new("text");
511 let inner = BytesStart::new("inner");
512
513 writer
514 .write_event_async(Event::Start(start.clone()))
515 .await
516 .expect("write start tag failed");
517 writer
518 .write_event_async(Event::Text(text))
519 .await
520 .expect("write text failed");
521 writer
522 .write_event_async(Event::Empty(inner))
523 .await
524 .expect("write inner tag failed");
525 writer
526 .write_event_async(Event::End(end))
527 .await
528 .expect("write end tag failed");
529
530 assert_eq!(
531 std::str::from_utf8(&buffer).unwrap(),
532 r#"<paired attr1="value1" attr2="value2">text<inner/>
533</paired>"#
534 );
535 }
536
537 #[tokio::test]
538 async fn nested() {
539 let mut buffer = Vec::new();
540 let mut writer = Writer::new_with_indent(&mut buffer, b' ', 4);
541
542 let start = BytesStart::new("paired")
543 .with_attributes(vec![("attr1", "value1"), ("attr2", "value2")].into_iter());
544 let end = start.to_end();
545 let inner = BytesStart::new("inner");
546
547 writer
548 .write_event_async(Event::Start(start.clone()))
549 .await
550 .expect("write start 1 tag failed");
551 writer
552 .write_event_async(Event::Start(start.clone()))
553 .await
554 .expect("write start 2 tag failed");
555 writer
556 .write_event_async(Event::Empty(inner))
557 .await
558 .expect("write inner tag failed");
559 writer
560 .write_event_async(Event::End(end.clone()))
561 .await
562 .expect("write end tag 2 failed");
563 writer
564 .write_event_async(Event::End(end))
565 .await
566 .expect("write end tag 1 failed");
567
568 assert_eq!(
569 std::str::from_utf8(&buffer).unwrap(),
570 r#"<paired attr1="value1" attr2="value2">
571 <paired attr1="value1" attr2="value2">
572 <inner/>
573 </paired>
574</paired>"#
575 );
576 }
577}