1use std::io;
2use std::mem;
3use std::os::raw;
4use std::slice;
5
6use crate::{EmitterError, Event};
7use crate::sys;
8
9pub struct Emitter<'a> {
11 inner: sys::yaml_emitter_t,
12 writer: Box<dyn io::Write + 'a>,
13 writer_error: Option<io::Error>,
14}
15
16impl<'a> Emitter<'a> {
17 pub fn new<W: io::Write + 'a>(writer: W) -> Result<Box<Self>, EmitterError> {
24 let mut inner = unsafe { mem::MaybeUninit::zeroed().assume_init() };
25
26 if unsafe { sys::yaml_emitter_initialize(&mut inner) }.ok {
27 let mut emitter = Box::new(Self {
28 inner,
29 writer: Box::new(writer),
30 writer_error: None,
31 });
32
33 unsafe {
34 sys::yaml_emitter_set_output(
35 &mut emitter.inner,
36 write_handler,
37 emitter.as_mut() as *mut _ as *mut _,
38 );
39 }
40
41 Ok(emitter)
42 } else {
43 Err(EmitterError::LibYamlError)
44 }
45 }
46
47 pub fn emit(&mut self, event: Event) -> Result<(), EmitterError> {
49 if unsafe { sys::yaml_emitter_emit(&mut self.inner, &mut event.into_raw()?) }.ok {
50 debug_assert!(self.writer_error.is_none());
51 Ok(())
52 } else {
53 match mem::replace(&mut self.writer_error, None) {
54 Some(e) => Err(EmitterError::IoError(e)),
55 None => Err(EmitterError::LibYamlError),
56 }
57 }
58 }
59
60 pub fn flush(&mut self) -> Result<(), EmitterError> {
62 if unsafe { sys::yaml_emitter_flush(&mut self.inner) }.ok {
63 Ok(())
64 } else {
65 Err(EmitterError::LibYamlError)
66 }
67 }
68
69 pub fn as_raw_ptr(&mut self) -> *mut sys::yaml_emitter_t {
71 &mut self.inner
72 }
73}
74
75impl Drop for Emitter<'_> {
76 fn drop(&mut self) {
77 unsafe {
78 sys::yaml_emitter_delete(&mut self.inner)
79 }
80 }
81}
82
83unsafe fn write_handler(
84 data: *mut raw::c_void,
85 buffer: *mut raw::c_uchar,
86 mut size: u64,
87) -> raw::c_int {
88 let emitter = &mut *(data as *mut Emitter);
89
90 while size != 0 {
91 emitter.writer_error = emitter.writer
92 .write_all(slice::from_raw_parts(buffer, size.min(usize::MAX as _) as _))
93 .err();
94
95 size -= size.min(usize::MAX as _);
96 }
97
98 if emitter.writer_error.is_none() { 1 } else { 0 }
99}