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