mirror of
https://github.com/simonask/libyaml-safer
synced 2024-11-22 19:33:03 +00:00
Emitter: Rustify errors
This commit is contained in:
parent
28f28b472b
commit
d1357d92df
7 changed files with 131 additions and 161 deletions
|
@ -2,7 +2,7 @@ use alloc::string::String;
|
|||
use alloc::vec::Vec;
|
||||
|
||||
use crate::externs::memcpy;
|
||||
use crate::yaml::{size_t, Write, YamlEventData, YamlNodeData};
|
||||
use crate::yaml::{size_t, YamlEventData, YamlNodeData};
|
||||
use crate::{
|
||||
libc, yaml_break_t, yaml_document_t, yaml_emitter_t, yaml_encoding_t, yaml_event_t,
|
||||
yaml_mapping_style_t, yaml_mark_t, yaml_node_pair_t, yaml_node_t, yaml_parser_t,
|
||||
|
@ -146,7 +146,7 @@ pub fn yaml_emitter_delete(emitter: &mut yaml_emitter_t) {
|
|||
/// YAML_WRITE_ERROR error.
|
||||
pub unsafe fn yaml_emitter_set_output_string<'w>(
|
||||
emitter: &mut yaml_emitter_t<'w>,
|
||||
output: &'w mut String,
|
||||
output: &'w mut Vec<u8>,
|
||||
) {
|
||||
__assert!(emitter.write_handler.is_none());
|
||||
if emitter.encoding == YAML_ANY_ENCODING {
|
||||
|
@ -161,7 +161,7 @@ pub unsafe fn yaml_emitter_set_output_string<'w>(
|
|||
/// Set a generic output handler.
|
||||
pub unsafe fn yaml_emitter_set_output<'w>(
|
||||
emitter: &mut yaml_emitter_t<'w>,
|
||||
handler: &'w mut dyn Write,
|
||||
handler: &'w mut dyn std::io::Write,
|
||||
) {
|
||||
__assert!(emitter.write_handler.is_none());
|
||||
emitter.write_handler = Some(handler);
|
||||
|
|
|
@ -23,9 +23,8 @@ use libyaml_safer::{
|
|||
yaml_sequence_end_event_initialize, yaml_sequence_start_event_initialize,
|
||||
yaml_stream_end_event_initialize, yaml_stream_start_event_initialize, YAML_ANY_SCALAR_STYLE,
|
||||
YAML_BLOCK_MAPPING_STYLE, YAML_BLOCK_SEQUENCE_STYLE, YAML_DOUBLE_QUOTED_SCALAR_STYLE,
|
||||
YAML_EMITTER_ERROR, YAML_FOLDED_SCALAR_STYLE, YAML_LITERAL_SCALAR_STYLE, YAML_MEMORY_ERROR,
|
||||
YAML_PLAIN_SCALAR_STYLE, YAML_SINGLE_QUOTED_SCALAR_STYLE, YAML_UTF8_ENCODING,
|
||||
YAML_WRITER_ERROR,
|
||||
YAML_FOLDED_SCALAR_STYLE, YAML_LITERAL_SCALAR_STYLE, YAML_PLAIN_SCALAR_STYLE,
|
||||
YAML_SINGLE_QUOTED_SCALAR_STYLE, YAML_UTF8_ENCODING,
|
||||
};
|
||||
use std::env;
|
||||
use std::error::Error;
|
||||
|
@ -34,16 +33,6 @@ use std::io::{self, BufRead, Read, Write};
|
|||
use std::mem::MaybeUninit;
|
||||
use std::process::ExitCode;
|
||||
|
||||
struct WrapWrite<'w>(&'w mut dyn Write);
|
||||
impl<'w> libyaml_safer::Write for WrapWrite<'w> {
|
||||
fn write(&mut self, buffer: &[u8]) -> bool {
|
||||
match Write::write(self.0, buffer) {
|
||||
Ok(n) => n != 0,
|
||||
Err(_) => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) unsafe fn unsafe_main(
|
||||
stdin: &mut dyn Read,
|
||||
stdout: &mut dyn Write,
|
||||
|
@ -54,9 +43,7 @@ pub(crate) unsafe fn unsafe_main(
|
|||
}
|
||||
let mut emitter = emitter.assume_init();
|
||||
|
||||
let mut stdout = WrapWrite(stdout);
|
||||
|
||||
yaml_emitter_set_output(&mut emitter, &mut stdout);
|
||||
yaml_emitter_set_output(&mut emitter, stdout);
|
||||
yaml_emitter_set_canonical(&mut emitter, false);
|
||||
yaml_emitter_set_unicode(&mut emitter, false);
|
||||
|
||||
|
@ -126,22 +113,8 @@ pub(crate) unsafe fn unsafe_main(
|
|||
if result.is_err() {
|
||||
break Err("Memory error: Not enough memory for creating an event".into());
|
||||
}
|
||||
if yaml_emitter_emit(&mut emitter, event).is_err() {
|
||||
break Err(match emitter.error {
|
||||
YAML_MEMORY_ERROR => "Memory error: Not enough memory for emitting".into(),
|
||||
YAML_WRITER_ERROR => format!(
|
||||
"Writer error: {}",
|
||||
emitter.problem.unwrap_or("<NO ERROR MESSAGE>")
|
||||
)
|
||||
.into(),
|
||||
YAML_EMITTER_ERROR => format!(
|
||||
"Emitter error: {}",
|
||||
emitter.problem.unwrap_or("<NO ERROR MESSAGE>")
|
||||
)
|
||||
.into(),
|
||||
// Couldn't happen.
|
||||
_ => "Internal error".into(),
|
||||
});
|
||||
if let Err(err) = yaml_emitter_emit(&mut emitter, event) {
|
||||
break Err(err.into());
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -2,15 +2,15 @@ use alloc::string::String;
|
|||
use alloc::vec;
|
||||
|
||||
use crate::yaml::{
|
||||
yaml_anchors_t, yaml_document_t, yaml_emitter_t, yaml_event_t, yaml_node_t, YamlEventData,
|
||||
YamlNodeData, YAML_ANY_ENCODING,
|
||||
yaml_anchors_t, yaml_document_t, yaml_emitter_t, yaml_event_t, yaml_node_t, EmitterError,
|
||||
YamlEventData, YamlNodeData, YAML_ANY_ENCODING,
|
||||
};
|
||||
use crate::{libc, yaml_document_delete, yaml_emitter_emit};
|
||||
|
||||
/// Start a YAML stream.
|
||||
///
|
||||
/// This function should be used before yaml_emitter_dump() is called.
|
||||
pub fn yaml_emitter_open(emitter: &mut yaml_emitter_t) -> Result<(), ()> {
|
||||
pub fn yaml_emitter_open(emitter: &mut yaml_emitter_t) -> Result<(), EmitterError> {
|
||||
__assert!(!emitter.opened);
|
||||
let event = yaml_event_t {
|
||||
data: YamlEventData::StreamStart {
|
||||
|
@ -26,7 +26,7 @@ pub fn yaml_emitter_open(emitter: &mut yaml_emitter_t) -> Result<(), ()> {
|
|||
/// Finish a YAML stream.
|
||||
///
|
||||
/// This function should be used after yaml_emitter_dump() is called.
|
||||
pub fn yaml_emitter_close(emitter: &mut yaml_emitter_t) -> Result<(), ()> {
|
||||
pub fn yaml_emitter_close(emitter: &mut yaml_emitter_t) -> Result<(), EmitterError> {
|
||||
__assert!(emitter.opened);
|
||||
if emitter.closed {
|
||||
return Ok(());
|
||||
|
@ -49,11 +49,11 @@ pub fn yaml_emitter_close(emitter: &mut yaml_emitter_t) -> Result<(), ()> {
|
|||
pub fn yaml_emitter_dump(
|
||||
emitter: &mut yaml_emitter_t,
|
||||
document: &mut yaml_document_t,
|
||||
) -> Result<(), ()> {
|
||||
) -> Result<(), EmitterError> {
|
||||
if !emitter.opened {
|
||||
if let Err(()) = yaml_emitter_open(emitter) {
|
||||
if let Err(err) = yaml_emitter_open(emitter) {
|
||||
yaml_emitter_delete_document_and_anchors(emitter, document);
|
||||
return Err(());
|
||||
return Err(err);
|
||||
}
|
||||
}
|
||||
if document.nodes.is_empty() {
|
||||
|
@ -156,7 +156,7 @@ fn yaml_emitter_dump_node(
|
|||
emitter: &mut yaml_emitter_t,
|
||||
document: &mut yaml_document_t,
|
||||
index: libc::c_int,
|
||||
) -> Result<(), ()> {
|
||||
) -> Result<(), EmitterError> {
|
||||
let node = &mut document.nodes[index as usize - 1];
|
||||
let anchor_id: libc::c_int = emitter.anchors[index as usize - 1].anchor;
|
||||
let mut anchor: Option<String> = None;
|
||||
|
@ -179,7 +179,10 @@ fn yaml_emitter_dump_node(
|
|||
}
|
||||
}
|
||||
|
||||
fn yaml_emitter_dump_alias(emitter: &mut yaml_emitter_t, anchor: String) -> Result<(), ()> {
|
||||
fn yaml_emitter_dump_alias(
|
||||
emitter: &mut yaml_emitter_t,
|
||||
anchor: String,
|
||||
) -> Result<(), EmitterError> {
|
||||
let event = yaml_event_t {
|
||||
data: YamlEventData::Alias { anchor },
|
||||
..Default::default()
|
||||
|
@ -191,7 +194,7 @@ fn yaml_emitter_dump_scalar(
|
|||
emitter: &mut yaml_emitter_t,
|
||||
node: yaml_node_t,
|
||||
anchor: Option<String>,
|
||||
) -> Result<(), ()> {
|
||||
) -> Result<(), EmitterError> {
|
||||
// TODO: Extract this constant as `YAML_DEFAULT_SCALAR_TAG` (source: dumper.c)
|
||||
let plain_implicit = node.tag.as_deref() == Some("tag:yaml.org,2002:str");
|
||||
let quoted_implicit = node.tag.as_deref() == Some("tag:yaml.org,2002:str"); // TODO: Why compare twice?! (even the C code does this)
|
||||
|
@ -219,7 +222,7 @@ fn yaml_emitter_dump_sequence(
|
|||
document: &mut yaml_document_t,
|
||||
node: yaml_node_t,
|
||||
anchor: Option<String>,
|
||||
) -> Result<(), ()> {
|
||||
) -> Result<(), EmitterError> {
|
||||
// TODO: YAML_DEFAULT_SEQUENCE_TAG
|
||||
let implicit = node.tag.as_deref() == Some("tag:yaml.org,2002:seq");
|
||||
|
||||
|
@ -253,7 +256,7 @@ fn yaml_emitter_dump_mapping(
|
|||
document: &mut yaml_document_t,
|
||||
node: yaml_node_t,
|
||||
anchor: Option<String>,
|
||||
) -> Result<(), ()> {
|
||||
) -> Result<(), EmitterError> {
|
||||
// TODO: YAML_DEFAULT_MAPPING_TAG
|
||||
let implicit = node.tag.as_deref() == Some("tag:yaml.org,2002:map");
|
||||
|
||||
|
|
126
src/emitter.rs
126
src/emitter.rs
|
@ -5,12 +5,12 @@ use crate::macros::{
|
|||
is_alpha, is_ascii, is_blank, is_blankz, is_bom, is_break, is_printable, is_space,
|
||||
};
|
||||
use crate::ops::ForceMul as _;
|
||||
use crate::yaml::YamlEventData;
|
||||
use crate::yaml::{EmitterError, WriterError, YamlEventData};
|
||||
use crate::{
|
||||
libc, yaml_emitter_flush, yaml_emitter_t, yaml_event_delete, yaml_event_t, yaml_scalar_style_t,
|
||||
yaml_tag_directive_t, yaml_version_directive_t, YAML_ANY_BREAK, YAML_ANY_ENCODING,
|
||||
YAML_ANY_SCALAR_STYLE, YAML_CRLN_BREAK, YAML_CR_BREAK, YAML_DOUBLE_QUOTED_SCALAR_STYLE,
|
||||
YAML_EMITTER_ERROR, YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE, YAML_EMIT_BLOCK_MAPPING_KEY_STATE,
|
||||
YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE, YAML_EMIT_BLOCK_MAPPING_KEY_STATE,
|
||||
YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE, YAML_EMIT_BLOCK_MAPPING_VALUE_STATE,
|
||||
YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE, YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE,
|
||||
YAML_EMIT_DOCUMENT_CONTENT_STATE, YAML_EMIT_DOCUMENT_END_STATE, YAML_EMIT_DOCUMENT_START_STATE,
|
||||
|
@ -23,7 +23,7 @@ use crate::{
|
|||
YAML_SINGLE_QUOTED_SCALAR_STYLE, YAML_UTF8_ENCODING,
|
||||
};
|
||||
|
||||
fn FLUSH(emitter: &mut yaml_emitter_t) -> Result<(), ()> {
|
||||
fn FLUSH(emitter: &mut yaml_emitter_t) -> Result<(), WriterError> {
|
||||
if emitter.buffer.len() < OUTPUT_BUFFER_SIZE - 5 {
|
||||
Ok(())
|
||||
} else {
|
||||
|
@ -31,7 +31,7 @@ fn FLUSH(emitter: &mut yaml_emitter_t) -> Result<(), ()> {
|
|||
}
|
||||
}
|
||||
|
||||
fn PUT(emitter: &mut yaml_emitter_t, value: u8) -> Result<(), ()> {
|
||||
fn PUT(emitter: &mut yaml_emitter_t, value: u8) -> Result<(), WriterError> {
|
||||
FLUSH(emitter)?;
|
||||
let ch = char::try_from(value).expect("invalid char");
|
||||
emitter.buffer.push(ch);
|
||||
|
@ -39,7 +39,7 @@ fn PUT(emitter: &mut yaml_emitter_t, value: u8) -> Result<(), ()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn PUT_BREAK(emitter: &mut yaml_emitter_t) -> Result<(), ()> {
|
||||
fn PUT_BREAK(emitter: &mut yaml_emitter_t) -> Result<(), WriterError> {
|
||||
FLUSH(emitter)?;
|
||||
if emitter.line_break == YAML_CR_BREAK {
|
||||
emitter.buffer.push('\r');
|
||||
|
@ -55,21 +55,21 @@ fn PUT_BREAK(emitter: &mut yaml_emitter_t) -> Result<(), ()> {
|
|||
|
||||
/// Write UTF-8 charanters from `string` to `emitter` and increment
|
||||
/// `emitter.column` the appropriate number of times.
|
||||
fn WRITE_STR(emitter: &mut yaml_emitter_t, string: &str) -> Result<(), ()> {
|
||||
fn WRITE_STR(emitter: &mut yaml_emitter_t, string: &str) -> Result<(), WriterError> {
|
||||
for ch in string.chars() {
|
||||
WRITE_CHAR(emitter, ch)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn WRITE_CHAR(emitter: &mut yaml_emitter_t, ch: char) -> Result<(), ()> {
|
||||
fn WRITE_CHAR(emitter: &mut yaml_emitter_t, ch: char) -> Result<(), WriterError> {
|
||||
FLUSH(emitter)?;
|
||||
emitter.buffer.push(ch);
|
||||
emitter.column += 1;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn WRITE_BREAK_CHAR(emitter: &mut yaml_emitter_t, ch: char) -> Result<(), ()> {
|
||||
fn WRITE_BREAK_CHAR(emitter: &mut yaml_emitter_t, ch: char) -> Result<(), WriterError> {
|
||||
FLUSH(emitter)?;
|
||||
if ch == '\n' {
|
||||
_ = PUT_BREAK(emitter);
|
||||
|
@ -115,13 +115,11 @@ struct ScalarAnalysis<'a> {
|
|||
pub style: yaml_scalar_style_t,
|
||||
}
|
||||
|
||||
fn yaml_emitter_set_emitter_error(
|
||||
emitter: &mut yaml_emitter_t,
|
||||
fn yaml_emitter_set_emitter_error<T>(
|
||||
_emitter: &mut yaml_emitter_t,
|
||||
problem: &'static str,
|
||||
) -> Result<(), ()> {
|
||||
emitter.error = YAML_EMITTER_ERROR;
|
||||
emitter.problem = Some(problem);
|
||||
Err(())
|
||||
) -> Result<T, EmitterError> {
|
||||
Err(EmitterError::Problem(problem))
|
||||
}
|
||||
|
||||
/// Emit an event.
|
||||
|
@ -130,7 +128,10 @@ fn yaml_emitter_set_emitter_error(
|
|||
/// The emitter takes the responsibility for the event object and destroys its
|
||||
/// content after it is emitted. The event object is destroyed even if the
|
||||
/// function fails.
|
||||
pub fn yaml_emitter_emit(emitter: &mut yaml_emitter_t, event: yaml_event_t) -> Result<(), ()> {
|
||||
pub fn yaml_emitter_emit(
|
||||
emitter: &mut yaml_emitter_t,
|
||||
event: yaml_event_t,
|
||||
) -> Result<(), EmitterError> {
|
||||
emitter.events.push_back(event);
|
||||
while let Some(mut event) = yaml_emitter_needs_mode_events(emitter) {
|
||||
let tag_directives = core::mem::take(&mut emitter.tag_directives);
|
||||
|
@ -193,7 +194,7 @@ fn yaml_emitter_append_tag_directive(
|
|||
emitter: &mut yaml_emitter_t,
|
||||
value: &yaml_tag_directive_t,
|
||||
allow_duplicates: bool,
|
||||
) -> Result<(), ()> {
|
||||
) -> Result<(), EmitterError> {
|
||||
for tag_directive in emitter.tag_directives.iter() {
|
||||
if value.handle == tag_directive.handle {
|
||||
if allow_duplicates {
|
||||
|
@ -219,7 +220,7 @@ fn yaml_emitter_state_machine(
|
|||
emitter: &mut yaml_emitter_t,
|
||||
event: &yaml_event_t,
|
||||
analysis: &mut Analysis,
|
||||
) -> Result<(), ()> {
|
||||
) -> Result<(), EmitterError> {
|
||||
match emitter.state {
|
||||
YAML_EMIT_STREAM_START_STATE => yaml_emitter_emit_stream_start(emitter, event),
|
||||
YAML_EMIT_FIRST_DOCUMENT_START_STATE => {
|
||||
|
@ -275,7 +276,7 @@ fn yaml_emitter_state_machine(
|
|||
fn yaml_emitter_emit_stream_start(
|
||||
emitter: &mut yaml_emitter_t,
|
||||
event: &yaml_event_t,
|
||||
) -> Result<(), ()> {
|
||||
) -> Result<(), EmitterError> {
|
||||
emitter.open_ended = 0;
|
||||
if let YamlEventData::StreamStart { ref encoding } = event.data {
|
||||
if emitter.encoding == YAML_ANY_ENCODING {
|
||||
|
@ -314,7 +315,7 @@ fn yaml_emitter_emit_document_start(
|
|||
emitter: &mut yaml_emitter_t,
|
||||
event: &yaml_event_t,
|
||||
first: bool,
|
||||
) -> Result<(), ()> {
|
||||
) -> Result<(), EmitterError> {
|
||||
if let YamlEventData::DocumentStart {
|
||||
version_directive,
|
||||
tag_directives,
|
||||
|
@ -404,7 +405,7 @@ fn yaml_emitter_emit_document_content(
|
|||
emitter: &mut yaml_emitter_t,
|
||||
event: &yaml_event_t,
|
||||
analysis: &mut Analysis,
|
||||
) -> Result<(), ()> {
|
||||
) -> Result<(), EmitterError> {
|
||||
emitter.states.push(YAML_EMIT_DOCUMENT_END_STATE);
|
||||
yaml_emitter_emit_node(emitter, event, true, false, false, false, analysis)
|
||||
}
|
||||
|
@ -412,7 +413,7 @@ fn yaml_emitter_emit_document_content(
|
|||
fn yaml_emitter_emit_document_end(
|
||||
emitter: &mut yaml_emitter_t,
|
||||
event: &yaml_event_t,
|
||||
) -> Result<(), ()> {
|
||||
) -> Result<(), EmitterError> {
|
||||
if let YamlEventData::DocumentEnd { implicit } = &event.data {
|
||||
let implicit = *implicit;
|
||||
yaml_emitter_write_indent(emitter)?;
|
||||
|
@ -437,7 +438,7 @@ fn yaml_emitter_emit_flow_sequence_item(
|
|||
event: &yaml_event_t,
|
||||
first: bool,
|
||||
analysis: &mut Analysis,
|
||||
) -> Result<(), ()> {
|
||||
) -> Result<(), EmitterError> {
|
||||
if first {
|
||||
yaml_emitter_write_indicator(emitter, "[", true, true, false)?;
|
||||
yaml_emitter_increase_indent(emitter, true, false);
|
||||
|
@ -469,7 +470,7 @@ fn yaml_emitter_emit_flow_mapping_key(
|
|||
event: &yaml_event_t,
|
||||
first: bool,
|
||||
analysis: &mut Analysis,
|
||||
) -> Result<(), ()> {
|
||||
) -> Result<(), EmitterError> {
|
||||
if first {
|
||||
yaml_emitter_write_indicator(emitter, "{", true, true, false)?;
|
||||
yaml_emitter_increase_indent(emitter, true, false);
|
||||
|
@ -477,7 +478,7 @@ fn yaml_emitter_emit_flow_mapping_key(
|
|||
}
|
||||
if let YamlEventData::MappingEnd = &event.data {
|
||||
if emitter.indents.is_empty() {
|
||||
return Err(());
|
||||
panic!("emitter.indents should not be empty");
|
||||
}
|
||||
emitter.flow_level -= 1;
|
||||
emitter.indent = emitter.indents.pop().unwrap();
|
||||
|
@ -512,7 +513,7 @@ fn yaml_emitter_emit_flow_mapping_value(
|
|||
event: &yaml_event_t,
|
||||
simple: bool,
|
||||
analysis: &mut Analysis,
|
||||
) -> Result<(), ()> {
|
||||
) -> Result<(), EmitterError> {
|
||||
if simple {
|
||||
yaml_emitter_write_indicator(emitter, ":", false, false, false)?;
|
||||
} else {
|
||||
|
@ -530,7 +531,7 @@ fn yaml_emitter_emit_block_sequence_item(
|
|||
event: &yaml_event_t,
|
||||
first: bool,
|
||||
analysis: &mut Analysis,
|
||||
) -> Result<(), ()> {
|
||||
) -> Result<(), EmitterError> {
|
||||
if first {
|
||||
yaml_emitter_increase_indent(
|
||||
emitter,
|
||||
|
@ -554,7 +555,7 @@ fn yaml_emitter_emit_block_mapping_key(
|
|||
event: &yaml_event_t,
|
||||
first: bool,
|
||||
analysis: &mut Analysis,
|
||||
) -> Result<(), ()> {
|
||||
) -> Result<(), EmitterError> {
|
||||
if first {
|
||||
yaml_emitter_increase_indent(emitter, false, false);
|
||||
}
|
||||
|
@ -581,7 +582,7 @@ fn yaml_emitter_emit_block_mapping_value(
|
|||
event: &yaml_event_t,
|
||||
simple: bool,
|
||||
analysis: &mut Analysis,
|
||||
) -> Result<(), ()> {
|
||||
) -> Result<(), EmitterError> {
|
||||
if simple {
|
||||
yaml_emitter_write_indicator(emitter, ":", false, false, false)?;
|
||||
} else {
|
||||
|
@ -600,7 +601,7 @@ fn yaml_emitter_emit_node(
|
|||
mapping: bool,
|
||||
simple_key: bool,
|
||||
analysis: &mut Analysis,
|
||||
) -> Result<(), ()> {
|
||||
) -> Result<(), EmitterError> {
|
||||
emitter.root_context = root;
|
||||
emitter.sequence_context = sequence;
|
||||
emitter.mapping_context = mapping;
|
||||
|
@ -626,7 +627,7 @@ fn yaml_emitter_emit_alias(
|
|||
emitter: &mut yaml_emitter_t,
|
||||
_event: &yaml_event_t,
|
||||
analysis: &Option<AnchorAnalysis>,
|
||||
) -> Result<(), ()> {
|
||||
) -> Result<(), EmitterError> {
|
||||
yaml_emitter_process_anchor(emitter, analysis)?;
|
||||
if emitter.simple_key_context {
|
||||
PUT(emitter, b' ')?;
|
||||
|
@ -639,7 +640,7 @@ fn yaml_emitter_emit_scalar(
|
|||
emitter: &mut yaml_emitter_t,
|
||||
event: &yaml_event_t,
|
||||
analysis: &mut Analysis,
|
||||
) -> Result<(), ()> {
|
||||
) -> Result<(), EmitterError> {
|
||||
let Analysis {
|
||||
anchor,
|
||||
tag,
|
||||
|
@ -663,7 +664,7 @@ fn yaml_emitter_emit_sequence_start(
|
|||
emitter: &mut yaml_emitter_t,
|
||||
event: &yaml_event_t,
|
||||
analysis: &Analysis,
|
||||
) -> Result<(), ()> {
|
||||
) -> Result<(), EmitterError> {
|
||||
let Analysis { anchor, tag, .. } = analysis;
|
||||
yaml_emitter_process_anchor(emitter, anchor)?;
|
||||
yaml_emitter_process_tag(emitter, tag)?;
|
||||
|
@ -690,7 +691,7 @@ fn yaml_emitter_emit_mapping_start(
|
|||
emitter: &mut yaml_emitter_t,
|
||||
event: &yaml_event_t,
|
||||
analysis: &Analysis,
|
||||
) -> Result<(), ()> {
|
||||
) -> Result<(), EmitterError> {
|
||||
let Analysis { anchor, tag, .. } = analysis;
|
||||
yaml_emitter_process_anchor(emitter, anchor)?;
|
||||
yaml_emitter_process_tag(emitter, tag)?;
|
||||
|
@ -811,7 +812,7 @@ fn yaml_emitter_select_scalar_style(
|
|||
event: &yaml_event_t,
|
||||
scalar_analysis: &mut ScalarAnalysis,
|
||||
tag_analysis: &mut Option<TagAnalysis>,
|
||||
) -> Result<(), ()> {
|
||||
) -> Result<(), EmitterError> {
|
||||
if let YamlEventData::Scalar {
|
||||
plain_implicit,
|
||||
quoted_implicit,
|
||||
|
@ -880,7 +881,7 @@ fn yaml_emitter_select_scalar_style(
|
|||
fn yaml_emitter_process_anchor(
|
||||
emitter: &mut yaml_emitter_t,
|
||||
analysis: &Option<AnchorAnalysis>,
|
||||
) -> Result<(), ()> {
|
||||
) -> Result<(), EmitterError> {
|
||||
let Some(analysis) = analysis.as_ref() else {
|
||||
return Ok(());
|
||||
};
|
||||
|
@ -897,7 +898,7 @@ fn yaml_emitter_process_anchor(
|
|||
fn yaml_emitter_process_tag(
|
||||
emitter: &mut yaml_emitter_t,
|
||||
analysis: &Option<TagAnalysis>,
|
||||
) -> Result<(), ()> {
|
||||
) -> Result<(), EmitterError> {
|
||||
let Some(analysis) = analysis.as_ref() else {
|
||||
return Ok(());
|
||||
};
|
||||
|
@ -921,7 +922,7 @@ fn yaml_emitter_process_tag(
|
|||
fn yaml_emitter_process_scalar(
|
||||
emitter: &mut yaml_emitter_t,
|
||||
analysis: &ScalarAnalysis,
|
||||
) -> Result<(), ()> {
|
||||
) -> Result<(), EmitterError> {
|
||||
match analysis.style {
|
||||
YAML_PLAIN_SCALAR_STYLE => {
|
||||
return yaml_emitter_write_plain_scalar(
|
||||
|
@ -950,15 +951,14 @@ fn yaml_emitter_process_scalar(
|
|||
YAML_FOLDED_SCALAR_STYLE => {
|
||||
return yaml_emitter_write_folded_scalar(emitter, analysis.value);
|
||||
}
|
||||
_ => {}
|
||||
YAML_ANY_SCALAR_STYLE => unreachable!("No scalar style chosen"),
|
||||
}
|
||||
Err(())
|
||||
}
|
||||
|
||||
fn yaml_emitter_analyze_version_directive(
|
||||
emitter: &mut yaml_emitter_t,
|
||||
version_directive: &yaml_version_directive_t,
|
||||
) -> Result<(), ()> {
|
||||
) -> Result<(), EmitterError> {
|
||||
if version_directive.major != 1 || version_directive.minor != 1 && version_directive.minor != 2
|
||||
{
|
||||
return yaml_emitter_set_emitter_error(emitter, "incompatible %YAML directive");
|
||||
|
@ -969,7 +969,7 @@ fn yaml_emitter_analyze_version_directive(
|
|||
fn yaml_emitter_analyze_tag_directive(
|
||||
emitter: &mut yaml_emitter_t,
|
||||
tag_directive: &yaml_tag_directive_t,
|
||||
) -> Result<(), ()> {
|
||||
) -> Result<(), EmitterError> {
|
||||
if tag_directive.handle.is_empty() {
|
||||
return yaml_emitter_set_emitter_error(emitter, "tag handle must not be empty");
|
||||
}
|
||||
|
@ -1002,7 +1002,7 @@ fn yaml_emitter_analyze_anchor<'a>(
|
|||
emitter: &mut yaml_emitter_t,
|
||||
anchor: &'a str,
|
||||
alias: bool,
|
||||
) -> Result<AnchorAnalysis<'a>, ()> {
|
||||
) -> Result<AnchorAnalysis<'a>, EmitterError> {
|
||||
if anchor.is_empty() {
|
||||
yaml_emitter_set_emitter_error(
|
||||
emitter,
|
||||
|
@ -1034,7 +1034,7 @@ fn yaml_emitter_analyze_tag<'a>(
|
|||
emitter: &mut yaml_emitter_t,
|
||||
tag: &'a str,
|
||||
tag_directives: &'a [yaml_tag_directive_t],
|
||||
) -> Result<TagAnalysis<'a>, ()> {
|
||||
) -> Result<TagAnalysis<'a>, EmitterError> {
|
||||
if tag.is_empty() {
|
||||
yaml_emitter_set_emitter_error(emitter, "tag value must not be empty")?;
|
||||
}
|
||||
|
@ -1057,7 +1057,7 @@ fn yaml_emitter_analyze_tag<'a>(
|
|||
fn yaml_emitter_analyze_scalar<'a>(
|
||||
emitter: &mut yaml_emitter_t,
|
||||
value: &'a str,
|
||||
) -> Result<ScalarAnalysis<'a>, ()> {
|
||||
) -> Result<ScalarAnalysis<'a>, EmitterError> {
|
||||
let mut block_indicators = false;
|
||||
let mut flow_indicators = false;
|
||||
let mut line_breaks = false;
|
||||
|
@ -1224,7 +1224,7 @@ fn yaml_emitter_analyze_event<'a>(
|
|||
emitter: &mut yaml_emitter_t,
|
||||
event: &'a yaml_event_t,
|
||||
tag_directives: &'a [yaml_tag_directive_t],
|
||||
) -> Result<Analysis<'a>, ()> {
|
||||
) -> Result<Analysis<'a>, EmitterError> {
|
||||
let mut analysis = Analysis::default();
|
||||
|
||||
match &event.data {
|
||||
|
@ -1292,13 +1292,13 @@ fn yaml_emitter_analyze_event<'a>(
|
|||
Ok(analysis)
|
||||
}
|
||||
|
||||
fn yaml_emitter_write_bom(emitter: &mut yaml_emitter_t) -> Result<(), ()> {
|
||||
fn yaml_emitter_write_bom(emitter: &mut yaml_emitter_t) -> Result<(), EmitterError> {
|
||||
FLUSH(emitter)?;
|
||||
emitter.buffer.push('\u{feff}');
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn yaml_emitter_write_indent(emitter: &mut yaml_emitter_t) -> Result<(), ()> {
|
||||
fn yaml_emitter_write_indent(emitter: &mut yaml_emitter_t) -> Result<(), EmitterError> {
|
||||
let indent: libc::c_int = if emitter.indent >= 0 {
|
||||
emitter.indent
|
||||
} else {
|
||||
|
@ -1324,7 +1324,7 @@ fn yaml_emitter_write_indicator(
|
|||
need_whitespace: bool,
|
||||
is_whitespace: bool,
|
||||
is_indention: bool,
|
||||
) -> Result<(), ()> {
|
||||
) -> Result<(), EmitterError> {
|
||||
if need_whitespace && !emitter.whitespace {
|
||||
PUT(emitter, b' ')?;
|
||||
}
|
||||
|
@ -1334,14 +1334,20 @@ fn yaml_emitter_write_indicator(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn yaml_emitter_write_anchor(emitter: &mut yaml_emitter_t, value: &str) -> Result<(), ()> {
|
||||
fn yaml_emitter_write_anchor(
|
||||
emitter: &mut yaml_emitter_t,
|
||||
value: &str,
|
||||
) -> Result<(), EmitterError> {
|
||||
WRITE_STR(emitter, value)?;
|
||||
emitter.whitespace = false;
|
||||
emitter.indention = false;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn yaml_emitter_write_tag_handle(emitter: &mut yaml_emitter_t, value: &str) -> Result<(), ()> {
|
||||
fn yaml_emitter_write_tag_handle(
|
||||
emitter: &mut yaml_emitter_t,
|
||||
value: &str,
|
||||
) -> Result<(), EmitterError> {
|
||||
if !emitter.whitespace {
|
||||
PUT(emitter, b' ')?;
|
||||
}
|
||||
|
@ -1355,7 +1361,7 @@ fn yaml_emitter_write_tag_content(
|
|||
emitter: &mut yaml_emitter_t,
|
||||
value: &str,
|
||||
need_whitespace: bool,
|
||||
) -> Result<(), ()> {
|
||||
) -> Result<(), EmitterError> {
|
||||
if need_whitespace && !emitter.whitespace {
|
||||
PUT(emitter, b' ')?;
|
||||
}
|
||||
|
@ -1396,7 +1402,7 @@ fn yaml_emitter_write_plain_scalar(
|
|||
emitter: &mut yaml_emitter_t,
|
||||
value: &str,
|
||||
allow_breaks: bool,
|
||||
) -> Result<(), ()> {
|
||||
) -> Result<(), EmitterError> {
|
||||
let mut spaces = false;
|
||||
let mut breaks = false;
|
||||
if !emitter.whitespace && (!value.is_empty() || emitter.flow_level != 0) {
|
||||
|
@ -1440,7 +1446,7 @@ fn yaml_emitter_write_single_quoted_scalar(
|
|||
emitter: &mut yaml_emitter_t,
|
||||
value: &str,
|
||||
allow_breaks: bool,
|
||||
) -> Result<(), ()> {
|
||||
) -> Result<(), EmitterError> {
|
||||
let mut spaces = false;
|
||||
let mut breaks = false;
|
||||
yaml_emitter_write_indicator(emitter, "'", true, false, false)?;
|
||||
|
@ -1498,7 +1504,7 @@ fn yaml_emitter_write_double_quoted_scalar(
|
|||
emitter: &mut yaml_emitter_t,
|
||||
value: &str,
|
||||
allow_breaks: bool,
|
||||
) -> Result<(), ()> {
|
||||
) -> Result<(), EmitterError> {
|
||||
let mut spaces = false;
|
||||
yaml_emitter_write_indicator(emitter, "\"", true, false, false)?;
|
||||
let mut chars = value.chars();
|
||||
|
@ -1615,7 +1621,7 @@ fn yaml_emitter_write_double_quoted_scalar(
|
|||
fn yaml_emitter_write_block_scalar_hints(
|
||||
emitter: &mut yaml_emitter_t,
|
||||
string: &str,
|
||||
) -> Result<(), ()> {
|
||||
) -> Result<(), EmitterError> {
|
||||
let mut chomp_hint: Option<&str> = None;
|
||||
|
||||
let first = string.chars().next();
|
||||
|
@ -1655,7 +1661,10 @@ fn yaml_emitter_write_block_scalar_hints(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn yaml_emitter_write_literal_scalar(emitter: &mut yaml_emitter_t, value: &str) -> Result<(), ()> {
|
||||
fn yaml_emitter_write_literal_scalar(
|
||||
emitter: &mut yaml_emitter_t,
|
||||
value: &str,
|
||||
) -> Result<(), EmitterError> {
|
||||
let mut breaks = true;
|
||||
yaml_emitter_write_indicator(emitter, "|", true, false, false)?;
|
||||
yaml_emitter_write_block_scalar_hints(emitter, value)?;
|
||||
|
@ -1680,7 +1689,10 @@ fn yaml_emitter_write_literal_scalar(emitter: &mut yaml_emitter_t, value: &str)
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn yaml_emitter_write_folded_scalar(emitter: &mut yaml_emitter_t, value: &str) -> Result<(), ()> {
|
||||
fn yaml_emitter_write_folded_scalar(
|
||||
emitter: &mut yaml_emitter_t,
|
||||
value: &str,
|
||||
) -> Result<(), EmitterError> {
|
||||
let mut breaks = true;
|
||||
let mut leading_spaces = true;
|
||||
yaml_emitter_write_indicator(emitter, ">", true, false, false)?;
|
||||
|
|
12
src/lib.rs
12
src/lib.rs
|
@ -4,7 +4,6 @@
|
|||
//! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust
|
||||
//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs
|
||||
|
||||
#![no_std]
|
||||
#![doc(html_root_url = "https://docs.rs/unsafe-libyaml/0.2.10")]
|
||||
#![allow(non_camel_case_types, non_snake_case, unsafe_op_in_unsafe_fn)]
|
||||
#![warn(clippy::pedantic)]
|
||||
|
@ -150,7 +149,7 @@ pub use crate::yaml::{
|
|||
yaml_node_item_t, yaml_node_pair_t, yaml_node_t, yaml_parser_state_t, yaml_parser_t,
|
||||
yaml_read_handler_t, yaml_scalar_style_t, yaml_sequence_style_t, yaml_simple_key_t,
|
||||
yaml_tag_directive_t, yaml_token_t, yaml_token_type_t, yaml_version_directive_t,
|
||||
yaml_write_handler_t, Read, Write, YamlEventData,
|
||||
yaml_write_handler_t, YamlEventData,
|
||||
};
|
||||
#[doc(hidden)]
|
||||
pub use crate::yaml::{
|
||||
|
@ -161,6 +160,8 @@ pub use crate::yaml::{
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use alloc::vec::Vec;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
|
@ -269,7 +270,7 @@ tie-fighter: '|\-*-/|'
|
|||
fn integration_hs5t() {
|
||||
unsafe {
|
||||
let mut emitter = emitter_new();
|
||||
let mut output = alloc::string::String::new();
|
||||
let mut output = Vec::new();
|
||||
yaml_emitter_set_output_string(&mut emitter, &mut output);
|
||||
|
||||
let mut event = yaml_event_t::default();
|
||||
|
@ -293,7 +294,10 @@ tie-fighter: '|\-*-/|'
|
|||
yaml_stream_end_event_initialize(&mut event).unwrap();
|
||||
yaml_emitter_emit(&mut emitter, core::mem::take(&mut event)).unwrap();
|
||||
|
||||
assert_eq!(output, "'1st non-empty\n\n 2nd non-empty 3rd non-empty'\n");
|
||||
assert_eq!(
|
||||
core::str::from_utf8(&output),
|
||||
Ok("'1st non-empty\n\n 2nd non-empty 3rd non-empty'\n")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,37 +1,32 @@
|
|||
use crate::yaml::WriterError;
|
||||
use crate::yaml_encoding_t::YAML_UTF16BE_ENCODING;
|
||||
use crate::{
|
||||
yaml_emitter_t, YAML_ANY_ENCODING, YAML_UTF16LE_ENCODING, YAML_UTF8_ENCODING, YAML_WRITER_ERROR,
|
||||
};
|
||||
|
||||
fn yaml_emitter_set_writer_error(
|
||||
emitter: &mut yaml_emitter_t,
|
||||
problem: &'static str,
|
||||
) -> Result<(), ()> {
|
||||
emitter.error = YAML_WRITER_ERROR;
|
||||
emitter.problem = Some(problem);
|
||||
Err(())
|
||||
}
|
||||
use crate::{yaml_emitter_t, YAML_ANY_ENCODING, YAML_UTF16LE_ENCODING, YAML_UTF8_ENCODING};
|
||||
|
||||
/// Flush the accumulated characters to the output.
|
||||
pub fn yaml_emitter_flush(emitter: &mut yaml_emitter_t) -> Result<(), ()> {
|
||||
pub fn yaml_emitter_flush(emitter: &mut yaml_emitter_t) -> Result<(), WriterError> {
|
||||
__assert!((emitter.write_handler).is_some());
|
||||
__assert!(emitter.encoding != YAML_ANY_ENCODING);
|
||||
|
||||
if emitter.buffer.is_empty() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// TODO: Support partial writes. These calls fail unless the writer is able
|
||||
// to write absolutely everything in the buffer.
|
||||
|
||||
if emitter.encoding == YAML_UTF8_ENCODING {
|
||||
let to_emit = emitter.buffer.as_bytes();
|
||||
if emitter
|
||||
.write_handler
|
||||
.as_mut()
|
||||
.expect("non-null function pointer")
|
||||
.write(to_emit)
|
||||
.expect("non-null writer")
|
||||
.write(to_emit)?
|
||||
== to_emit.len()
|
||||
{
|
||||
emitter.buffer.clear();
|
||||
return Ok(());
|
||||
} else {
|
||||
return yaml_emitter_set_writer_error(emitter, "write error");
|
||||
return Err(WriterError::Incomplete);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -56,12 +51,13 @@ pub fn yaml_emitter_flush(emitter: &mut yaml_emitter_t) -> Result<(), ()> {
|
|||
.write_handler
|
||||
.as_mut()
|
||||
.expect("non-null function pointer")
|
||||
.write(to_emit)
|
||||
.write(to_emit)?
|
||||
== to_emit.len()
|
||||
{
|
||||
emitter.buffer.clear();
|
||||
emitter.raw_buffer.clear();
|
||||
Ok(())
|
||||
} else {
|
||||
yaml_emitter_set_writer_error(emitter, "write error")
|
||||
return Err(WriterError::Incomplete);
|
||||
}
|
||||
}
|
||||
|
|
52
src/yaml.rs
52
src/yaml.rs
|
@ -86,6 +86,22 @@ pub enum yaml_error_type_t {
|
|||
YAML_EMITTER_ERROR = 7,
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum EmitterError {
|
||||
#[error("{0}")]
|
||||
Problem(&'static str),
|
||||
#[error(transparent)]
|
||||
Writer(#[from] WriterError),
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum WriterError {
|
||||
#[error("writer could not flush the entire buffer")]
|
||||
Incomplete,
|
||||
#[error(transparent)]
|
||||
Io(#[from] std::io::Error),
|
||||
}
|
||||
|
||||
/// The pointer position.
|
||||
#[derive(Copy, Clone, Default, Debug)]
|
||||
#[repr(C)]
|
||||
|
@ -872,12 +888,8 @@ pub(crate) struct yaml_anchors_t {
|
|||
#[repr(C)]
|
||||
#[non_exhaustive]
|
||||
pub struct yaml_emitter_t<'w> {
|
||||
/// Error type.
|
||||
pub error: yaml_error_type_t,
|
||||
/// Error description.
|
||||
pub problem: Option<&'static str>,
|
||||
/// Write handler.
|
||||
pub(crate) write_handler: Option<&'w mut dyn Write>,
|
||||
pub(crate) write_handler: Option<&'w mut dyn std::io::Write>,
|
||||
/// Standard (string or file) output data.
|
||||
pub(crate) output: unnamed_yaml_emitter_t_output_string,
|
||||
/// The working buffer.
|
||||
|
@ -947,8 +959,6 @@ pub struct yaml_emitter_t<'w> {
|
|||
impl<'a> Default for yaml_emitter_t<'a> {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
error: Default::default(),
|
||||
problem: Default::default(),
|
||||
write_handler: None,
|
||||
output: Default::default(),
|
||||
buffer: Default::default(),
|
||||
|
@ -1002,31 +1012,3 @@ impl Default for unnamed_yaml_emitter_t_output_string {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Write {
|
||||
fn write(&mut self, buffer: &[u8]) -> bool;
|
||||
}
|
||||
|
||||
pub trait Read {
|
||||
fn read(&mut self, buffer: &mut [u8]) -> usize;
|
||||
}
|
||||
|
||||
impl Write for Vec<u8> {
|
||||
fn write(&mut self, buffer: &[u8]) -> bool {
|
||||
self.extend(buffer);
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
impl Write for String {
|
||||
fn write(&mut self, buffer: &[u8]) -> bool {
|
||||
self.push_str(core::str::from_utf8(buffer).expect("invalid UTF-8"));
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
impl Write for &mut &mut [u8] {
|
||||
fn write(&mut self, buffer: &[u8]) -> bool {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue