#![forbid(unsafe_code)]
use std::io::Write;
use docspec_core::{Event, EventSink, Result};
use docspec_json::{JsonEmitter, StrusonBackend};
pub struct OxaWriter<W: Write> {
document_open: bool,
in_paragraph: bool,
json: JsonEmitter<StrusonBackend<W>>,
}
impl<W: Write> OxaWriter<W> {
fn close_paragraph(&mut self) -> Result<()> {
if !self.in_paragraph {
return Ok(());
}
self.json.close_array()?;
self.json.close_object()?;
self.in_paragraph = false;
Ok(())
}
#[inline]
#[must_use]
pub fn new(writer: W) -> Self {
Self {
document_open: false,
in_paragraph: false,
json: JsonEmitter::new(StrusonBackend::new(writer)),
}
}
}
impl<W: Write> EventSink for OxaWriter<W> {
#[inline]
fn finish(self) -> Result<()> {
self.json.finish().map(|_| ())
}
#[inline]
fn handle_event(&mut self, event: Event) -> Result<()> {
match event {
Event::StartDocument { .. } => {
if self.document_open {
return Ok(());
}
self.json.open_object()?;
self.json.key("type").value("Document")?;
self.json.key("children").open_array()?;
self.document_open = true;
Ok(())
}
Event::EndDocument => {
if !self.document_open {
return Ok(());
}
self.close_paragraph()?;
self.json.close_array()?;
self.json.close_object()?;
self.document_open = false;
Ok(())
}
Event::StartParagraph { .. } => {
if !self.document_open || self.in_paragraph {
return Ok(());
}
self.json.open_object()?;
self.json.key("type").value("Paragraph")?;
self.json.key("children").open_array()?;
self.in_paragraph = true;
Ok(())
}
Event::EndParagraph => self.close_paragraph(),
Event::Text { content } => {
if !self.in_paragraph {
return Ok(());
}
self.json.object(|j| {
j.key("type").value("Text")?;
j.key("value").value(content.as_str())
})
}
Event::EndBlockQuote
| Event::EndCaption
| Event::EndDefinitionDetail
| Event::EndDefinitionList
| Event::EndDefinitionTerm
| Event::EndFootnote
| Event::EndHeading
| Event::EndLink
| Event::EndOrderedListItem
| Event::EndPreformatted
| Event::EndTable
| Event::EndTableCell
| Event::EndTableHeader
| Event::EndTableRow
| Event::EndTextStyle
| Event::EndUnorderedListItem
| Event::FootnoteRef { .. }
| Event::Image { .. }
| Event::LineBreak
| Event::SoftBreak
| Event::StartBlockQuote { .. }
| Event::StartCaption { .. }
| Event::StartDefinitionDetail { .. }
| Event::StartDefinitionList { .. }
| Event::StartDefinitionTerm { .. }
| Event::StartFootnote { .. }
| Event::StartHeading { .. }
| Event::StartLink { .. }
| Event::StartOrderedListItem { .. }
| Event::StartPreformatted { .. }
| Event::StartTable { .. }
| Event::StartTableCell { .. }
| Event::StartTableHeader { .. }
| Event::StartTableRow { .. }
| Event::StartTextStyle { .. }
| Event::StartUnorderedListItem { .. }
| Event::ThematicBreak { .. }
| _ => Ok(()),
}
}
}