diff --git a/Cargo.toml b/Cargo.toml index ce16414..9007cc3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,9 +20,6 @@ unsafe-libyaml-test-suite = { path = "tests/data" } [lib] doc-scrape-examples = false -[dependencies] -thiserror = "1.0" - [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] rustdoc-args = ["--generate-link-to-definition"] diff --git a/README.md b/README.md index 4c59b4d..c3d8568 100644 --- a/README.md +++ b/README.md @@ -45,10 +45,6 @@ errors may be reported with reduced fidelity compared with libyaml (e.g., error messages may look slightly different), but the same inputs should generate the same general errors. -This library introduces no new dependencies except for -[`thiserror`](https://docs.rs/thiserror) for convenience. This dependency may go -away in the future. - ### Compatibility and interoperability While this library matches the behavior of libyaml, it is not intended as a diff --git a/src/document.rs b/src/document.rs index 5594eac..b7c63ed 100644 --- a/src/document.rs +++ b/src/document.rs @@ -1,6 +1,6 @@ use crate::{ - AliasData, Anchors, ComposerError, Emitter, EmitterError, Event, EventData, MappingStyle, Mark, - Parser, ScalarStyle, SequenceStyle, TagDirective, VersionDirective, DEFAULT_MAPPING_TAG, + AliasData, Anchors, Emitter, Error, Event, EventData, MappingStyle, Mark, Parser, Result, + ScalarStyle, SequenceStyle, TagDirective, VersionDirective, DEFAULT_MAPPING_TAG, DEFAULT_SCALAR_TAG, DEFAULT_SEQUENCE_TAG, }; @@ -249,7 +249,7 @@ impl Document { /// /// An application must not alternate the calls of [`Document::load()`] with /// the calls of [`Parser::parse()`]. Doing this will break the parser. - pub fn load(parser: &mut Parser) -> Result { + pub fn load(parser: &mut Parser) -> Result { let mut document = Document::new(None, &[], false, false); document.nodes.reserve(16); @@ -262,14 +262,14 @@ impl Document { Ok(_) => panic!("expected stream start"), Err(err) => { parser.delete_aliases(); - return Err(err.into()); + return Err(err); } } } if parser.scanner.stream_end_produced { return Ok(document); } - let err: ComposerError; + let err: Error; match parser.parse() { Ok(event) => { if let EventData::StreamEnd = &event.data { @@ -284,37 +284,13 @@ impl Document { Err(e) => err = e, } } - Err(e) => err = e.into(), + Err(e) => err = e, } parser.delete_aliases(); Err(err) } - fn set_composer_error( - problem: &'static str, - problem_mark: Mark, - ) -> Result { - Err(ComposerError::Problem { - problem, - mark: problem_mark, - }) - } - - fn set_composer_error_context( - context: &'static str, - context_mark: Mark, - problem: &'static str, - problem_mark: Mark, - ) -> Result { - Err(ComposerError::ProblemWithContext { - context, - context_mark, - problem, - mark: problem_mark, - }) - } - - fn load_document(&mut self, parser: &mut Parser, event: Event) -> Result<(), ComposerError> { + fn load_document(&mut self, parser: &mut Parser, event: Event) -> Result<()> { let mut ctx = vec![]; if let EventData::DocumentStart { version_directive, @@ -338,7 +314,7 @@ impl Document { } } - fn load_nodes(&mut self, parser: &mut Parser, ctx: &mut Vec) -> Result<(), ComposerError> { + fn load_nodes(&mut self, parser: &mut Parser, ctx: &mut Vec) -> Result<()> { let end_implicit; let end_mark; @@ -383,7 +359,7 @@ impl Document { parser: &mut Parser, index: i32, anchor: Option, - ) -> Result<(), ComposerError> { + ) -> Result<()> { let Some(anchor) = anchor else { return Ok(()); }; @@ -394,19 +370,19 @@ impl Document { }; for alias_data in &parser.aliases { if alias_data.anchor == data.anchor { - return Self::set_composer_error_context( + return Err(Error::composer( "found duplicate anchor; first occurrence", alias_data.mark, "second occurrence", data.mark, - ); + )); } } parser.aliases.push(data); Ok(()) } - fn load_node_add(&mut self, ctx: &[i32], index: i32) -> Result<(), ComposerError> { + fn load_node_add(&mut self, ctx: &[i32], index: i32) -> Result<()> { if ctx.is_empty() { return Ok(()); } @@ -439,12 +415,7 @@ impl Document { Ok(()) } - fn load_alias( - &mut self, - parser: &mut Parser, - event: Event, - ctx: &[i32], - ) -> Result<(), ComposerError> { + fn load_alias(&mut self, parser: &mut Parser, event: Event, ctx: &[i32]) -> Result<()> { let EventData::Alias { anchor } = &event.data else { unreachable!() }; @@ -455,15 +426,15 @@ impl Document { } } - Self::set_composer_error("found undefined alias", event.start_mark) + Err(Error::composer( + "", + Mark::default(), + "found undefined alias", + event.start_mark, + )) } - fn load_scalar( - &mut self, - parser: &mut Parser, - event: Event, - ctx: &[i32], - ) -> Result<(), ComposerError> { + fn load_scalar(&mut self, parser: &mut Parser, event: Event, ctx: &[i32]) -> Result<()> { let EventData::Scalar { mut tag, value, @@ -495,7 +466,7 @@ impl Document { parser: &mut Parser, event: Event, ctx: &mut Vec, - ) -> Result<(), ComposerError> { + ) -> Result<()> { let EventData::SequenceStart { anchor, mut tag, @@ -530,7 +501,7 @@ impl Document { Ok(()) } - fn load_sequence_end(&mut self, event: Event, ctx: &mut Vec) -> Result<(), ComposerError> { + fn load_sequence_end(&mut self, event: Event, ctx: &mut Vec) -> Result<()> { assert!(!ctx.is_empty()); let index: i32 = *ctx.last().unwrap(); assert!(matches!( @@ -547,7 +518,7 @@ impl Document { parser: &mut Parser, event: Event, ctx: &mut Vec, - ) -> Result<(), ComposerError> { + ) -> Result<()> { let EventData::MappingStart { anchor, mut tag, @@ -580,7 +551,7 @@ impl Document { Ok(()) } - fn load_mapping_end(&mut self, event: Event, ctx: &mut Vec) -> Result<(), ComposerError> { + fn load_mapping_end(&mut self, event: Event, ctx: &mut Vec) -> Result<()> { assert!(!ctx.is_empty()); let index: i32 = *ctx.last().unwrap(); assert!(matches!( @@ -596,7 +567,7 @@ impl Document { /// /// The document object may be generated using the [`Document::load()`] /// function or the [`Document::new()`] function. - pub fn dump(mut self, emitter: &mut Emitter) -> Result<(), EmitterError> { + pub fn dump(mut self, emitter: &mut Emitter) -> Result<()> { if !emitter.opened { if let Err(err) = emitter.open() { emitter.reset_anchors(); @@ -651,7 +622,7 @@ impl Document { } } - fn dump_node(&mut self, emitter: &mut Emitter, index: i32) -> Result<(), EmitterError> { + fn dump_node(&mut self, emitter: &mut Emitter, index: i32) -> Result<()> { let node = &mut self.nodes[index as usize - 1]; let anchor_id: i32 = emitter.anchors[index as usize - 1].anchor; let mut anchor: Option = None; @@ -672,16 +643,12 @@ impl Document { } } - fn dump_alias(emitter: &mut Emitter, anchor: String) -> Result<(), EmitterError> { + fn dump_alias(emitter: &mut Emitter, anchor: String) -> Result<()> { let event = Event::new(EventData::Alias { anchor }); emitter.emit(event) } - fn dump_scalar( - emitter: &mut Emitter, - node: Node, - anchor: Option, - ) -> Result<(), EmitterError> { + fn dump_scalar(emitter: &mut Emitter, node: Node, anchor: Option) -> Result<()> { let plain_implicit = node.tag.as_deref() == Some(DEFAULT_SCALAR_TAG); let quoted_implicit = node.tag.as_deref() == Some(DEFAULT_SCALAR_TAG); // TODO: Why compare twice?! (even the C code does this) @@ -704,7 +671,7 @@ impl Document { emitter: &mut Emitter, node: Node, anchor: Option, - ) -> Result<(), EmitterError> { + ) -> Result<()> { let implicit = node.tag.as_deref() == Some(DEFAULT_SEQUENCE_TAG); let NodeData::Sequence { items, style } = node.data else { @@ -730,7 +697,7 @@ impl Document { emitter: &mut Emitter, node: Node, anchor: Option, - ) -> Result<(), EmitterError> { + ) -> Result<()> { let implicit = node.tag.as_deref() == Some(DEFAULT_MAPPING_TAG); let NodeData::Mapping { pairs, style } = node.data else { diff --git a/src/emitter.rs b/src/emitter.rs index 55a0748..e697554 100644 --- a/src/emitter.rs +++ b/src/emitter.rs @@ -6,8 +6,8 @@ use crate::macros::{ is_alpha, is_ascii, is_blank, is_blankz, is_bom, is_break, is_breakz, is_printable, is_space, }; use crate::{ - Break, EmitterError, Encoding, Event, EventData, MappingStyle, ScalarStyle, SequenceStyle, - TagDirective, VersionDirective, WriterError, OUTPUT_BUFFER_SIZE, + Break, Encoding, Error, Event, EventData, MappingStyle, Result, ScalarStyle, SequenceStyle, + TagDirective, VersionDirective, OUTPUT_BUFFER_SIZE, }; /// The emitter structure. @@ -176,10 +176,6 @@ struct ScalarAnalysis<'a> { } impl<'w> Emitter<'w> { - fn set_emitter_error(problem: &'static str) -> Result { - Err(EmitterError::Problem(problem)) - } - /// Create an self. pub fn new() -> Emitter<'w> { Emitter { @@ -224,7 +220,7 @@ impl<'w> Emitter<'w> { /// /// This function should be used before /// [`Document::dump()`](crate::Document::dump) is called. - pub fn open(&mut self) -> Result<(), EmitterError> { + pub fn open(&mut self) -> Result<()> { assert!(!self.opened); let event = Event::stream_start(Encoding::Any); self.emit(event)?; @@ -236,7 +232,7 @@ impl<'w> Emitter<'w> { /// /// This function should be used after /// [`Document::dump()`](crate::Document::dump) is called. - pub fn close(&mut self) -> Result<(), EmitterError> { + pub fn close(&mut self) -> Result<()> { assert!(self.opened); if self.closed { return Ok(()); @@ -305,7 +301,7 @@ impl<'w> Emitter<'w> { /// [`Parser::parse()`](crate::Parser::parse) function. 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 emit(&mut self, event: Event) -> Result<(), EmitterError> { + pub fn emit(&mut self, event: Event) -> Result<()> { self.events.push_back(event); while let Some(event) = self.needs_mode_events() { let tag_directives = core::mem::take(&mut self.tag_directives); @@ -323,7 +319,7 @@ impl<'w> Emitter<'w> { } /// Equivalent of the libyaml `FLUSH` macro. - fn flush_if_needed(&mut self) -> Result<(), WriterError> { + fn flush_if_needed(&mut self) -> Result<()> { if self.buffer.len() < OUTPUT_BUFFER_SIZE - 5 { Ok(()) } else { @@ -332,7 +328,7 @@ impl<'w> Emitter<'w> { } /// Equivalent of the libyaml `PUT` macro. - fn put(&mut self, value: char) -> Result<(), WriterError> { + fn put(&mut self, value: char) -> Result<()> { self.flush_if_needed()?; self.buffer.push(value); self.column += 1; @@ -340,7 +336,7 @@ impl<'w> Emitter<'w> { } /// Equivalent of the libyaml `PUT_BREAK` macro. - fn put_break(&mut self) -> Result<(), WriterError> { + fn put_break(&mut self) -> Result<()> { self.flush_if_needed()?; if self.line_break == Break::Cr { self.buffer.push('\r'); @@ -357,7 +353,7 @@ impl<'w> Emitter<'w> { /// Write UTF-8 charanters from `string` to `emitter` and increment /// `emitter.column` the appropriate number of times. It is assumed that the /// string does not contain line breaks! - fn write_str(&mut self, string: &str) -> Result<(), WriterError> { + fn write_str(&mut self, string: &str) -> Result<()> { if self.buffer.len() + string.len() > OUTPUT_BUFFER_SIZE { self.flush()?; } @@ -376,7 +372,7 @@ impl<'w> Emitter<'w> { } /// Equivalent of the libyaml `WRITE` macro. - fn write_char(&mut self, ch: char) -> Result<(), WriterError> { + fn write_char(&mut self, ch: char) -> Result<()> { self.flush_if_needed()?; self.buffer.push(ch); self.column += 1; @@ -384,7 +380,7 @@ impl<'w> Emitter<'w> { } /// Equivalent of the libyaml `WRITE_BREAK` macro. - fn write_break(&mut self, ch: char) -> Result<(), WriterError> { + fn write_break(&mut self, ch: char) -> Result<()> { self.flush_if_needed()?; if ch == '\n' { self.put_break()?; @@ -437,17 +433,13 @@ impl<'w> Emitter<'w> { None } - fn append_tag_directive( - &mut self, - value: TagDirective, - allow_duplicates: bool, - ) -> Result<(), EmitterError> { + fn append_tag_directive(&mut self, value: TagDirective, allow_duplicates: bool) -> Result<()> { for tag_directive in &self.tag_directives { if value.handle == tag_directive.handle { if allow_duplicates { return Ok(()); } - return Self::set_emitter_error("duplicate %TAG directive"); + return Err(Error::emitter("duplicate %TAG directive")); } } self.tag_directives.push(value); @@ -463,11 +455,7 @@ impl<'w> Emitter<'w> { } } - fn state_machine<'a>( - &mut self, - event: &'a Event, - analysis: &mut Analysis<'a>, - ) -> Result<(), EmitterError> { + fn state_machine<'a>(&mut self, event: &'a Event, analysis: &mut Analysis<'a>) -> Result<()> { match self.state { EmitterState::StreamStart => self.emit_stream_start(event), EmitterState::FirstDocumentStart => self.emit_document_start(event, true), @@ -500,11 +488,11 @@ impl<'w> Emitter<'w> { EmitterState::BlockMappingValue => { self.emit_block_mapping_value(event, false, analysis) } - EmitterState::End => Self::set_emitter_error("expected nothing after STREAM-END"), + EmitterState::End => Err(Error::emitter("expected nothing after STREAM-END")), } } - fn emit_stream_start(&mut self, event: &Event) -> Result<(), EmitterError> { + fn emit_stream_start(&mut self, event: &Event) -> Result<()> { self.open_ended = 0; if let EventData::StreamStart { ref encoding } = event.data { if self.encoding == Encoding::Any { @@ -536,10 +524,10 @@ impl<'w> Emitter<'w> { self.state = EmitterState::FirstDocumentStart; return Ok(()); } - Self::set_emitter_error("expected STREAM-START") + Err(Error::emitter("expected STREAM-START")) } - fn emit_document_start(&mut self, event: &Event, first: bool) -> Result<(), EmitterError> { + fn emit_document_start(&mut self, event: &Event, first: bool) -> Result<()> { if let EventData::DocumentStart { version_directive, tag_directives, @@ -619,19 +607,15 @@ impl<'w> Emitter<'w> { return Ok(()); } - Self::set_emitter_error("expected DOCUMENT-START or STREAM-END") + Err(Error::emitter("expected DOCUMENT-START or STREAM-END")) } - fn emit_document_content( - &mut self, - event: &Event, - analysis: &mut Analysis, - ) -> Result<(), EmitterError> { + fn emit_document_content(&mut self, event: &Event, analysis: &mut Analysis) -> Result<()> { self.states.push(EmitterState::DocumentEnd); self.emit_node(event, true, false, false, false, analysis) } - fn emit_document_end(&mut self, event: &Event) -> Result<(), EmitterError> { + fn emit_document_end(&mut self, event: &Event) -> Result<()> { if let EventData::DocumentEnd { implicit } = &event.data { let implicit = *implicit; self.write_indent()?; @@ -648,7 +632,7 @@ impl<'w> Emitter<'w> { return Ok(()); } - Self::set_emitter_error("expected DOCUMENT-END") + Err(Error::emitter("expected DOCUMENT-END")) } fn emit_flow_sequence_item( @@ -656,7 +640,7 @@ impl<'w> Emitter<'w> { event: &Event, first: bool, analysis: &mut Analysis, - ) -> Result<(), EmitterError> { + ) -> Result<()> { if first { self.write_indicator("[", true, true, false)?; self.increase_indent(true, false); @@ -688,7 +672,7 @@ impl<'w> Emitter<'w> { event: &Event, first: bool, analysis: &mut Analysis, - ) -> Result<(), EmitterError> { + ) -> Result<()> { if first { self.write_indicator("{", true, true, false)?; self.increase_indent(true, false); @@ -727,7 +711,7 @@ impl<'w> Emitter<'w> { event: &Event, simple: bool, analysis: &mut Analysis, - ) -> Result<(), EmitterError> { + ) -> Result<()> { if simple { self.write_indicator(":", false, false, false)?; } else { @@ -745,7 +729,7 @@ impl<'w> Emitter<'w> { event: &Event, first: bool, analysis: &mut Analysis, - ) -> Result<(), EmitterError> { + ) -> Result<()> { if first { self.increase_indent(false, self.mapping_context && !self.indention); } @@ -765,7 +749,7 @@ impl<'w> Emitter<'w> { event: &Event, first: bool, analysis: &mut Analysis, - ) -> Result<(), EmitterError> { + ) -> Result<()> { if first { self.increase_indent(false, false); } @@ -790,7 +774,7 @@ impl<'w> Emitter<'w> { event: &Event, simple: bool, analysis: &mut Analysis, - ) -> Result<(), EmitterError> { + ) -> Result<()> { if simple { self.write_indicator(":", false, false, false)?; } else { @@ -809,7 +793,7 @@ impl<'w> Emitter<'w> { mapping: bool, simple_key: bool, analysis: &mut Analysis, - ) -> Result<(), EmitterError> { + ) -> Result<()> { self.root_context = root; self.sequence_context = sequence; self.mapping_context = mapping; @@ -820,17 +804,13 @@ impl<'w> Emitter<'w> { EventData::Scalar { .. } => self.emit_scalar(event, analysis), EventData::SequenceStart { .. } => self.emit_sequence_start(event, analysis), EventData::MappingStart { .. } => self.emit_mapping_start(event, analysis), - _ => { - Self::set_emitter_error("expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS") - } + _ => Err(Error::emitter( + "expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS", + )), } } - fn emit_alias( - &mut self, - _event: &Event, - analysis: &Option, - ) -> Result<(), EmitterError> { + fn emit_alias(&mut self, _event: &Event, analysis: &Option) -> Result<()> { self.process_anchor(analysis)?; if self.simple_key_context { self.put(' ')?; @@ -839,7 +819,7 @@ impl<'w> Emitter<'w> { Ok(()) } - fn emit_scalar(&mut self, event: &Event, analysis: &mut Analysis) -> Result<(), EmitterError> { + fn emit_scalar(&mut self, event: &Event, analysis: &mut Analysis) -> Result<()> { let Analysis { anchor, tag, @@ -859,11 +839,7 @@ impl<'w> Emitter<'w> { Ok(()) } - fn emit_sequence_start( - &mut self, - event: &Event, - analysis: &Analysis, - ) -> Result<(), EmitterError> { + fn emit_sequence_start(&mut self, event: &Event, analysis: &Analysis) -> Result<()> { let Analysis { anchor, tag, .. } = analysis; self.process_anchor(anchor)?; self.process_tag(tag)?; @@ -884,11 +860,7 @@ impl<'w> Emitter<'w> { Ok(()) } - fn emit_mapping_start( - &mut self, - event: &Event, - analysis: &Analysis, - ) -> Result<(), EmitterError> { + fn emit_mapping_start(&mut self, event: &Event, analysis: &Analysis) -> Result<()> { let Analysis { anchor, tag, .. } = analysis; self.process_anchor(anchor)?; self.process_tag(tag)?; @@ -980,7 +952,7 @@ impl<'w> Emitter<'w> { event: &Event, scalar_analysis: &mut ScalarAnalysis, tag_analysis: &mut Option, - ) -> Result<(), EmitterError> { + ) -> Result<()> { let EventData::Scalar { plain_implicit, quoted_implicit, @@ -994,7 +966,9 @@ impl<'w> Emitter<'w> { let mut style: ScalarStyle = *style; let no_tag = tag_analysis.is_none(); if no_tag && !*plain_implicit && !*quoted_implicit { - Self::set_emitter_error("neither tag nor implicit flags are specified")?; + return Err(Error::emitter( + "neither tag nor implicit flags are specified", + )); } if style == ScalarStyle::Any { style = ScalarStyle::Plain; @@ -1037,7 +1011,7 @@ impl<'w> Emitter<'w> { Ok(()) } - fn process_anchor(&mut self, analysis: &Option) -> Result<(), EmitterError> { + fn process_anchor(&mut self, analysis: &Option) -> Result<()> { let Some(analysis) = analysis.as_ref() else { return Ok(()); }; @@ -1045,7 +1019,7 @@ impl<'w> Emitter<'w> { self.write_anchor(analysis.anchor) } - fn process_tag(&mut self, analysis: &Option) -> Result<(), EmitterError> { + fn process_tag(&mut self, analysis: &Option) -> Result<()> { let Some(analysis) = analysis.as_ref() else { return Ok(()); }; @@ -1066,7 +1040,7 @@ impl<'w> Emitter<'w> { Ok(()) } - fn process_scalar(&mut self, analysis: &ScalarAnalysis) -> Result<(), EmitterError> { + fn process_scalar(&mut self, analysis: &ScalarAnalysis) -> Result<()> { match analysis.style { ScalarStyle::Plain => self.write_plain_scalar(analysis.value, !self.simple_key_context), ScalarStyle::SingleQuoted => { @@ -1081,59 +1055,59 @@ impl<'w> Emitter<'w> { } } - fn analyze_version_directive(version_directive: VersionDirective) -> Result<(), EmitterError> { + fn analyze_version_directive(version_directive: VersionDirective) -> Result<()> { if version_directive.major != 1 || version_directive.minor != 1 && version_directive.minor != 2 { - return Self::set_emitter_error("incompatible %YAML directive"); + return Err(Error::emitter("incompatible %YAML directive")); } Ok(()) } - fn analyze_tag_directive(tag_directive: &TagDirective) -> Result<(), EmitterError> { + fn analyze_tag_directive(tag_directive: &TagDirective) -> Result<()> { if tag_directive.handle.is_empty() { - return Self::set_emitter_error("tag handle must not be empty"); + return Err(Error::emitter("tag handle must not be empty")); } if !tag_directive.handle.starts_with('!') { - return Self::set_emitter_error("tag handle must start with '!'"); + return Err(Error::emitter("tag handle must start with '!'")); } if !tag_directive.handle.ends_with('!') { - return Self::set_emitter_error("tag handle must end with '!'"); + return Err(Error::emitter("tag handle must end with '!'")); } if tag_directive.handle.len() > 2 { let tag_content = &tag_directive.handle[1..tag_directive.handle.len() - 1]; for ch in tag_content.chars() { if !is_alpha(ch) { - return Self::set_emitter_error( + return Err(Error::emitter( "tag handle must contain alphanumerical characters only", - ); + )); } } } if tag_directive.prefix.is_empty() { - return Self::set_emitter_error("tag prefix must not be empty"); + return Err(Error::emitter("tag prefix must not be empty")); } Ok(()) } - fn analyze_anchor(anchor: &str, alias: bool) -> Result, EmitterError> { + fn analyze_anchor(anchor: &str, alias: bool) -> Result> { if anchor.is_empty() { - Self::set_emitter_error(if alias { + return Err(Error::emitter(if alias { "alias value must not be empty" } else { "anchor value must not be empty" - })?; + })); } for ch in anchor.chars() { if !is_alpha(ch) { - Self::set_emitter_error(if alias { + return Err(Error::emitter(if alias { "alias value must contain alphanumerical characters only" } else { "anchor value must contain alphanumerical characters only" - })?; + })); } } @@ -1143,9 +1117,9 @@ impl<'w> Emitter<'w> { fn analyze_tag<'a>( tag: &'a str, tag_directives: &'a [TagDirective], - ) -> Result, EmitterError> { + ) -> Result> { if tag.is_empty() { - Self::set_emitter_error("tag value must not be empty")?; + return Err(Error::emitter("tag value must not be empty")); } let mut handle = ""; @@ -1163,7 +1137,7 @@ impl<'w> Emitter<'w> { Ok(TagAnalysis { handle, suffix }) } - fn analyze_scalar<'a>(&mut self, value: &'a str) -> Result, EmitterError> { + fn analyze_scalar<'a>(&mut self, value: &'a str) -> Result> { let mut block_indicators = false; let mut flow_indicators = false; let mut line_breaks = false; @@ -1330,7 +1304,7 @@ impl<'w> Emitter<'w> { &mut self, event: &'a Event, tag_directives: &'a [TagDirective], - ) -> Result, EmitterError> { + ) -> Result> { let mut analysis = Analysis::default(); match &event.data { @@ -1389,13 +1363,13 @@ impl<'w> Emitter<'w> { Ok(analysis) } - fn write_bom(&mut self) -> Result<(), EmitterError> { + fn write_bom(&mut self) -> Result<()> { self.flush_if_needed()?; self.buffer.push('\u{feff}'); Ok(()) } - fn write_indent(&mut self) -> Result<(), EmitterError> { + fn write_indent(&mut self) -> Result<()> { let indent = if self.indent >= 0 { self.indent } else { 0 }; if !self.indention || self.column > indent || self.column == indent && !self.whitespace { self.put_break()?; @@ -1414,7 +1388,7 @@ impl<'w> Emitter<'w> { need_whitespace: bool, is_whitespace: bool, is_indention: bool, - ) -> Result<(), EmitterError> { + ) -> Result<()> { if need_whitespace && !self.whitespace { self.put(' ')?; } @@ -1424,14 +1398,14 @@ impl<'w> Emitter<'w> { Ok(()) } - fn write_anchor(&mut self, value: &str) -> Result<(), EmitterError> { + fn write_anchor(&mut self, value: &str) -> Result<()> { self.write_str(value)?; self.whitespace = false; self.indention = false; Ok(()) } - fn write_tag_handle(&mut self, value: &str) -> Result<(), EmitterError> { + fn write_tag_handle(&mut self, value: &str) -> Result<()> { if !self.whitespace { self.put(' ')?; } @@ -1441,11 +1415,7 @@ impl<'w> Emitter<'w> { Ok(()) } - fn write_tag_content( - &mut self, - value: &str, - need_whitespace: bool, - ) -> Result<(), EmitterError> { + fn write_tag_content(&mut self, value: &str, need_whitespace: bool) -> Result<()> { if need_whitespace && !self.whitespace { self.put(' ')?; } @@ -1486,7 +1456,7 @@ impl<'w> Emitter<'w> { Ok(()) } - fn write_plain_scalar(&mut self, value: &str, allow_breaks: bool) -> Result<(), EmitterError> { + fn write_plain_scalar(&mut self, value: &str, allow_breaks: bool) -> Result<()> { let mut spaces = false; let mut breaks = false; if !self.whitespace && (!value.is_empty() || self.flow_level != 0) { @@ -1526,11 +1496,7 @@ impl<'w> Emitter<'w> { Ok(()) } - fn write_single_quoted_scalar( - &mut self, - value: &str, - allow_breaks: bool, - ) -> Result<(), EmitterError> { + fn write_single_quoted_scalar(&mut self, value: &str, allow_breaks: bool) -> Result<()> { let mut spaces = false; let mut breaks = false; self.write_indicator("'", true, false, false)?; @@ -1584,11 +1550,7 @@ impl<'w> Emitter<'w> { Ok(()) } - fn write_double_quoted_scalar( - &mut self, - value: &str, - allow_breaks: bool, - ) -> Result<(), EmitterError> { + fn write_double_quoted_scalar(&mut self, value: &str, allow_breaks: bool) -> Result<()> { let mut spaces = false; self.write_indicator("\"", true, false, false)?; let mut chars = value.chars(); @@ -1701,7 +1663,7 @@ impl<'w> Emitter<'w> { Ok(()) } - fn write_block_scalar_hints(&mut self, string: &str) -> Result<(), EmitterError> { + fn write_block_scalar_hints(&mut self, string: &str) -> Result<()> { let mut chomp_hint: Option<&str> = None; let first = string.chars().next(); @@ -1736,7 +1698,7 @@ impl<'w> Emitter<'w> { Ok(()) } - fn write_literal_scalar(&mut self, value: &str) -> Result<(), EmitterError> { + fn write_literal_scalar(&mut self, value: &str) -> Result<()> { let mut breaks = true; self.write_indicator("|", true, false, false)?; self.write_block_scalar_hints(value)?; @@ -1761,7 +1723,7 @@ impl<'w> Emitter<'w> { Ok(()) } - fn write_folded_scalar(&mut self, value: &str) -> Result<(), EmitterError> { + fn write_folded_scalar(&mut self, value: &str) -> Result<()> { let mut breaks = true; let mut leading_spaces = true; self.write_indicator(">", true, false, false)?; @@ -1806,7 +1768,7 @@ impl<'w> Emitter<'w> { } /// Flush the accumulated characters to the output. - pub fn flush(&mut self) -> Result<(), WriterError> { + pub fn flush(&mut self) -> Result<()> { assert!((self.write_handler).is_some()); assert_ne!(self.encoding, Encoding::Any); diff --git a/src/error.rs b/src/error.rs index dce7452..d612462 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,5 +1,7 @@ +pub type Result = core::result::Result; + /// The pointer position. -#[derive(Copy, Clone, Default, Debug)] +#[derive(Copy, Clone, Default, Debug, PartialEq, Eq)] #[non_exhaustive] pub struct Mark { /// The position index. @@ -16,77 +18,230 @@ impl std::fmt::Display for Mark { } } -#[derive(Debug, thiserror::Error)] -pub enum EmitterError { - #[error("{0}")] - Problem(&'static str), - #[error(transparent)] - Writer(#[from] WriterError), +#[derive(Debug)] +#[allow(clippy::struct_field_names)] +struct Problem { + pub problem: &'static str, + pub problem_mark: Mark, + pub context: &'static str, + pub context_mark: Mark, } -#[derive(Debug, thiserror::Error)] -pub enum WriterError { - #[error(transparent)] - Io(#[from] std::io::Error), -} - -#[derive(Debug, thiserror::Error)] -pub enum ReaderError { - #[error("{problem}")] - Problem { +#[derive(Debug)] +enum ErrorImpl { + Reader { problem: &'static str, offset: usize, value: i32, }, - #[error("input stream produced an invalid byte order marker")] - InvalidBom, - #[error("invalid UTF-8 byte at offset: {value:x}")] - InvalidUtf8 { value: u8 }, - #[error("invalid UTF-16 unpaired surrogate: {value:x}")] - InvalidUtf16 { value: u16 }, - #[error(transparent)] - Io(#[from] std::io::Error), + Scanner(Problem), + Parser(Problem), + Composer(Problem), + Emitter(&'static str), + Io(std::io::Error), } -#[derive(Debug, thiserror::Error)] -pub enum ScannerError { - #[error("{}:{}: {} {} ({}:{})", problem_mark.line, problem_mark.column, problem, context, context_mark.line, context_mark.column)] - Problem { +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum ErrorKind { + Reader, + Scanner, + Parser, + Composer, + Emitter, + Io, +} + +#[derive(Debug)] +pub struct Error(Box); + +impl From for Error { + fn from(value: std::io::Error) -> Self { + Self(Box::new(ErrorImpl::Io(value))) + } +} + +impl Error { + pub(crate) fn reader(problem: &'static str, offset: usize, value: i32) -> Self { + Self(Box::new(ErrorImpl::Reader { + problem, + offset, + value, + })) + } + + pub(crate) fn scanner( context: &'static str, context_mark: Mark, problem: &'static str, problem_mark: Mark, - }, - #[error(transparent)] - Reader(#[from] ReaderError), -} + ) -> Self { + Self(Box::new(ErrorImpl::Scanner(Problem { + problem, + problem_mark, + context, + context_mark, + }))) + } -#[derive(Debug, thiserror::Error)] -pub enum ParserError { - #[error("{}:{}: {}", mark.line, mark.column, problem)] - Problem { problem: &'static str, mark: Mark }, - #[error("{}:{}: {} {} ({}:{})", mark.line, mark.column, problem, context, context_mark.line, context_mark.column)] - ProblemWithContext { + pub(crate) fn parser( context: &'static str, context_mark: Mark, problem: &'static str, - mark: Mark, - }, - #[error(transparent)] - Scanner(#[from] ScannerError), -} + problem_mark: Mark, + ) -> Self { + Self(Box::new(ErrorImpl::Parser(Problem { + problem, + problem_mark, + context, + context_mark, + }))) + } -#[derive(Debug, thiserror::Error)] -pub enum ComposerError { - #[error("{}:{}: {}", mark.line, mark.column, problem)] - Problem { problem: &'static str, mark: Mark }, - #[error("{}:{}: {} {} ({}:{})", mark.line, mark.column, problem, context, context_mark.line, context_mark.column)] - ProblemWithContext { + pub(crate) fn composer( context: &'static str, context_mark: Mark, problem: &'static str, - mark: Mark, - }, - #[error(transparent)] - Parser(#[from] ParserError), + problem_mark: Mark, + ) -> Self { + Self(Box::new(ErrorImpl::Composer(Problem { + problem, + problem_mark, + context, + context_mark, + }))) + } + + pub(crate) fn emitter(problem: &'static str) -> Self { + Self(Box::new(ErrorImpl::Emitter(problem))) + } + + pub fn kind(&self) -> ErrorKind { + match &*self.0 { + ErrorImpl::Reader { .. } => ErrorKind::Reader, + ErrorImpl::Scanner(_) => ErrorKind::Scanner, + ErrorImpl::Parser(_) => ErrorKind::Parser, + ErrorImpl::Composer(_) => ErrorKind::Composer, + ErrorImpl::Emitter(_) => ErrorKind::Emitter, + ErrorImpl::Io(_) => ErrorKind::Io, + } + } + + pub fn problem_mark(&self) -> Option { + match &*self.0 { + ErrorImpl::Reader { .. } | ErrorImpl::Emitter(_) | ErrorImpl::Io(_) => None, + ErrorImpl::Scanner(ref p) | ErrorImpl::Parser(ref p) | ErrorImpl::Composer(ref p) => { + Some(p.problem_mark) + } + } + } + + pub fn context_mark(&self) -> Option { + match &*self.0 { + ErrorImpl::Reader { .. } | ErrorImpl::Emitter(..) | ErrorImpl::Io(_) => None, + ErrorImpl::Scanner(ref p) | ErrorImpl::Parser(ref p) | ErrorImpl::Composer(ref p) => { + if p.context.is_empty() { + None + } else { + Some(p.context_mark) + } + } + } + } + + pub fn problem(&self) -> &'static str { + match &*self.0 { + ErrorImpl::Reader { problem, .. } | ErrorImpl::Emitter(problem) => problem, + ErrorImpl::Scanner(ref p) | ErrorImpl::Parser(ref p) | ErrorImpl::Composer(ref p) => { + p.problem + } + ErrorImpl::Io(_) => "I/O error", + } + } + + pub fn context(&self) -> Option<&'static str> { + match &*self.0 { + ErrorImpl::Reader { .. } | ErrorImpl::Emitter(..) | ErrorImpl::Io(_) => None, + ErrorImpl::Scanner(ref p) | ErrorImpl::Parser(ref p) | ErrorImpl::Composer(ref p) => { + if p.context.is_empty() { + None + } else { + Some(p.context) + } + } + } + } +} + +impl std::error::Error for Error { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + if let ErrorImpl::Io(ref err) = &*self.0 { + Some(err) + } else { + None + } + } +} + +impl TryFrom for std::io::Error { + type Error = Error; + + fn try_from(value: Error) -> Result { + if value.kind() == ErrorKind::Io { + if let ErrorImpl::Io(err) = *value.0 { + Ok(err) + } else { + unreachable!() + } + } else { + Err(value) + } + } +} + +impl core::fmt::Display for ErrorKind { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(match self { + ErrorKind::Reader => "Reader", + ErrorKind::Scanner => "Scanner", + ErrorKind::Parser => "Parser", + ErrorKind::Composer => "Composer", + ErrorKind::Emitter => "Emitter", + ErrorKind::Io => "I/O", + }) + } +} + +impl core::fmt::Display for Problem { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let Self { + problem, + problem_mark, + context, + context_mark, + } = self; + + if self.context.is_empty() { + write!(f, "{problem_mark}: {problem}") + } else { + write!(f, "{problem_mark}: {problem} {context} ({context_mark})") + } + } +} + +impl core::fmt::Display for Error { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{} error: ", self.kind())?; + match *self.0 { + ErrorImpl::Reader { + problem, + offset, + value, + } => write!(f, "{problem} (offset {offset}, value {value})"), + ErrorImpl::Scanner(ref p) | ErrorImpl::Parser(ref p) | ErrorImpl::Composer(ref p) => { + write!(f, "{p}") + } + ErrorImpl::Emitter(problem) => write!(f, "{problem}"), + ErrorImpl::Io(ref err) => write!(f, "{err}"), + } + } } diff --git a/src/parser.rs b/src/parser.rs index 80fcd3e..ec5fd5f 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -3,7 +3,7 @@ use alloc::{vec, vec::Vec}; use crate::scanner::Scanner; use crate::{ - Encoding, Event, EventData, MappingStyle, Mark, ParserError, ScalarStyle, SequenceStyle, + Encoding, Error, Event, EventData, MappingStyle, Mark, Result, ScalarStyle, SequenceStyle, TagDirective, TokenData, VersionDirective, }; @@ -110,7 +110,7 @@ pub struct AliasData { } impl<'r> Iterator for Parser<'r> { - type Item = Result; + type Item = Result; fn next(&mut self) -> Option { if self.scanner.stream_end_produced || self.state == ParserState::End { @@ -167,35 +167,14 @@ impl<'r> Parser<'r> { /// An application must not alternate the calls of [`Parser::parse()`] with /// the calls of [`Document::load()`](crate::Document::load). Doing this /// will break the parser. - pub fn parse(&mut self) -> Result { + pub fn parse(&mut self) -> Result { if self.scanner.stream_end_produced || self.state == ParserState::End { return Ok(Event::stream_end()); } self.state_machine() } - fn set_parser_error(problem: &'static str, problem_mark: Mark) -> Result { - Err(ParserError::Problem { - problem, - mark: problem_mark, - }) - } - - fn set_parser_error_context( - context: &'static str, - context_mark: Mark, - problem: &'static str, - problem_mark: Mark, - ) -> Result { - Err(ParserError::ProblemWithContext { - context, - context_mark, - problem, - mark: problem_mark, - }) - } - - fn state_machine(&mut self) -> Result { + fn state_machine(&mut self) -> Result { match self.state { ParserState::StreamStart => self.parse_stream_start(), ParserState::ImplicitDocumentStart => self.parse_document_start(true), @@ -230,7 +209,7 @@ impl<'r> Parser<'r> { } } - fn parse_stream_start(&mut self) -> Result { + fn parse_stream_start(&mut self) -> Result { let token = self.scanner.peek()?; if let TokenData::StreamStart { encoding } = &token.data { @@ -246,11 +225,16 @@ impl<'r> Parser<'r> { Ok(event) } else { let mark = token.start_mark; - Self::set_parser_error("did not find expected ", mark) + Err(Error::parser( + "", + Mark::default(), + "did not find expected ", + mark, + )) } } - fn parse_document_start(&mut self, implicit: bool) -> Result { + fn parse_document_start(&mut self, implicit: bool) -> Result { let mut version_directive: Option = None; let mut tag_directives = vec![]; @@ -304,7 +288,12 @@ impl<'r> Parser<'r> { self.scanner.skip_token(); Ok(event) } else { - Self::set_parser_error("did not find expected ", token.start_mark) + Err(Error::parser( + "", + Mark::default(), + "did not find expected ", + token.start_mark, + )) } } else { let event = Event { @@ -318,7 +307,7 @@ impl<'r> Parser<'r> { } } - fn parse_document_content(&mut self) -> Result { + fn parse_document_content(&mut self) -> Result { let token = self.scanner.peek()?; if let TokenData::VersionDirective { .. } | TokenData::TagDirective { .. } @@ -334,7 +323,7 @@ impl<'r> Parser<'r> { } } - fn parse_document_end(&mut self) -> Result { + fn parse_document_end(&mut self) -> Result { let mut end_mark: Mark; let mut implicit = true; let token = self.scanner.peek()?; @@ -354,7 +343,7 @@ impl<'r> Parser<'r> { }) } - fn parse_node(&mut self, block: bool, indentless_sequence: bool) -> Result { + fn parse_node(&mut self, block: bool, indentless_sequence: bool) -> Result { let mut anchor: Option = None; let mut tag_handle: Option = None; let mut tag_suffix: Option = None; @@ -424,12 +413,12 @@ impl<'r> Parser<'r> { } } if tag.is_none() { - return Self::set_parser_error_context( + return Err(Error::parser( "while parsing a node", start_mark, "found undefined tag handle", tag_mark, - ); + )); } } } @@ -548,7 +537,7 @@ impl<'r> Parser<'r> { }; return Ok(event); } else { - return Self::set_parser_error_context( + return Err(Error::parser( if block { "while parsing a block node" } else { @@ -557,11 +546,11 @@ impl<'r> Parser<'r> { start_mark, "did not find expected node content", token.start_mark, - ); + )); } } - fn parse_block_sequence_entry(&mut self, first: bool) -> Result { + fn parse_block_sequence_entry(&mut self, first: bool) -> Result { if first { let token = self.scanner.peek()?; let mark = token.start_mark; @@ -595,16 +584,16 @@ impl<'r> Parser<'r> { } else { let token_mark = token.start_mark; let mark = self.marks.pop().unwrap(); - return Self::set_parser_error_context( + return Err(Error::parser( "while parsing a block collection", mark, "did not find expected '-' indicator", token_mark, - ); + )); } } - fn parse_indentless_sequence_entry(&mut self) -> Result { + fn parse_indentless_sequence_entry(&mut self) -> Result { let mut token = self.scanner.peek()?; if let TokenData::BlockEntry = token.data { let mark: Mark = token.end_mark; @@ -632,7 +621,7 @@ impl<'r> Parser<'r> { } } - fn parse_block_mapping_key(&mut self, first: bool) -> Result { + fn parse_block_mapping_key(&mut self, first: bool) -> Result { if first { let token = self.scanner.peek()?; let mark = token.start_mark; @@ -668,16 +657,16 @@ impl<'r> Parser<'r> { } else { let token_mark = token.start_mark; let mark = self.marks.pop().unwrap(); - Self::set_parser_error_context( + Err(Error::parser( "while parsing a block mapping", mark, "did not find expected key", token_mark, - ) + )) } } - fn parse_block_mapping_value(&mut self) -> Result { + fn parse_block_mapping_value(&mut self) -> Result { let mut token = self.scanner.peek()?; if let TokenData::Value = token.data { let mark: Mark = token.end_mark; @@ -700,7 +689,7 @@ impl<'r> Parser<'r> { } } - fn parse_flow_sequence_entry(&mut self, first: bool) -> Result { + fn parse_flow_sequence_entry(&mut self, first: bool) -> Result { if first { let token = self.scanner.peek()?; let mark = token.start_mark; @@ -717,12 +706,12 @@ impl<'r> Parser<'r> { } else { let token_mark = token.start_mark; let mark = self.marks.pop().unwrap(); - return Self::set_parser_error_context( + return Err(Error::parser( "while parsing a flow sequence", mark, "did not find expected ',' or ']'", token_mark, - ); + )); } } if let TokenData::Key = token.data { @@ -755,7 +744,7 @@ impl<'r> Parser<'r> { Ok(event) } - fn parse_flow_sequence_entry_mapping_key(&mut self) -> Result { + fn parse_flow_sequence_entry_mapping_key(&mut self) -> Result { let token = self.scanner.peek()?; if matches!( token.data, @@ -771,7 +760,7 @@ impl<'r> Parser<'r> { } } - fn parse_flow_sequence_entry_mapping_value(&mut self) -> Result { + fn parse_flow_sequence_entry_mapping_value(&mut self) -> Result { let mut token = self.scanner.peek()?; if let TokenData::Value = token.data { self.scanner.skip_token(); @@ -789,7 +778,7 @@ impl<'r> Parser<'r> { Self::process_empty_scalar(mark) } - fn parse_flow_sequence_entry_mapping_end(&mut self) -> Result { + fn parse_flow_sequence_entry_mapping_end(&mut self) -> Result { let token = self.scanner.peek()?; let start_mark = token.start_mark; let end_mark = token.end_mark; @@ -801,7 +790,7 @@ impl<'r> Parser<'r> { }) } - fn parse_flow_mapping_key(&mut self, first: bool) -> Result { + fn parse_flow_mapping_key(&mut self, first: bool) -> Result { if first { let token = self.scanner.peek()?; let mark = token.start_mark; @@ -818,12 +807,12 @@ impl<'r> Parser<'r> { } else { let token_mark = token.start_mark; let mark = self.marks.pop().unwrap(); - return Self::set_parser_error_context( + return Err(Error::parser( "while parsing a flow mapping", mark, "did not find expected ',' or '}'", token_mark, - ); + )); } } if let TokenData::Key = token.data { @@ -855,7 +844,7 @@ impl<'r> Parser<'r> { Ok(event) } - fn parse_flow_mapping_value(&mut self, empty: bool) -> Result { + fn parse_flow_mapping_value(&mut self, empty: bool) -> Result { let mut token = self.scanner.peek()?; if empty { let mark = token.start_mark; @@ -875,7 +864,7 @@ impl<'r> Parser<'r> { Self::process_empty_scalar(mark) } - fn process_empty_scalar(mark: Mark) -> Result { + fn process_empty_scalar(mark: Mark) -> Result { Ok(Event { data: EventData::Scalar { anchor: None, @@ -894,7 +883,7 @@ impl<'r> Parser<'r> { &mut self, version_directive_ref: Option<&mut Option>, tag_directives_ref: Option<&mut Vec>, - ) -> Result<(), ParserError> { + ) -> Result<()> { let default_tag_directives: [TagDirective; 2] = [ // TODO: Get rid of these heap allocations. TagDirective { @@ -923,9 +912,19 @@ impl<'r> Parser<'r> { if let TokenData::VersionDirective { major, minor } = &token.data { let mark = token.start_mark; if version_directive.is_some() { - return Self::set_parser_error("found duplicate %YAML directive", mark); + return Err(Error::parser( + "", + Mark::default(), + "found duplicate %YAML directive", + mark, + )); } else if *major != 1 || *minor != 1 && *minor != 2 { - return Self::set_parser_error("found incompatible YAML document", mark); + return Err(Error::parser( + "", + Mark::default(), + "found incompatible YAML document", + mark, + )); } version_directive = Some(VersionDirective { major: *major, @@ -973,13 +972,18 @@ impl<'r> Parser<'r> { value: TagDirective, allow_duplicates: bool, mark: Mark, - ) -> Result<(), ParserError> { + ) -> Result<()> { for tag_directive in &self.tag_directives { if value.handle == tag_directive.handle { if allow_duplicates { return Ok(()); } - return Self::set_parser_error("found duplicate %TAG directive", mark); + return Err(Error::parser( + "", + Mark::default(), + "found duplicate %TAG directive", + mark, + )); } } self.tag_directives.push(value); diff --git a/src/reader.rs b/src/reader.rs index 93d39e3..9d154f7 100644 --- a/src/reader.rs +++ b/src/reader.rs @@ -2,27 +2,13 @@ use std::io::BufRead; use alloc::collections::VecDeque; -use crate::{scanner::Scanner, Encoding, ReaderError}; - -fn yaml_parser_set_reader_error( - problem: &'static str, - offset: usize, - value: i32, -) -> Result { - Err(ReaderError::Problem { - problem, - offset, - value, - }) -} +use crate::{scanner::Scanner, Encoding, Error, Result}; const BOM_UTF8: [u8; 3] = [0xef, 0xbb, 0xbf]; const BOM_UTF16LE: [u8; 2] = [0xff, 0xfe]; const BOM_UTF16BE: [u8; 2] = [0xfe, 0xff]; -fn yaml_parser_determine_encoding( - reader: &mut dyn BufRead, -) -> Result, ReaderError> { +fn yaml_parser_determine_encoding(reader: &mut dyn BufRead) -> Result> { let initial_bytes = reader.fill_buf()?; if initial_bytes.is_empty() { return Ok(None); @@ -35,7 +21,11 @@ fn yaml_parser_determine_encoding( if bom == BOM_UTF8 { Ok(Some(Encoding::Utf8)) } else { - Err(ReaderError::InvalidBom) + Err(Error::reader( + "invalid byte order marker", + 0, + i32::from_be_bytes([bom[0], bom[1], bom[2], 0]), + )) } } 0xff | 0xfe => { @@ -46,7 +36,11 @@ fn yaml_parser_determine_encoding( } else if bom == BOM_UTF16BE { Ok(Some(Encoding::Utf16Be)) } else { - Err(ReaderError::InvalidBom) + Err(Error::reader( + "invalid byte order marker", + 0, + i32::from_le_bytes([bom[0], bom[1], 0, 0]), + )) } } _ => Ok(Some(Encoding::Utf8)), @@ -60,7 +54,7 @@ fn read_utf8_buffered( reader: &mut dyn BufRead, out: &mut VecDeque, offset: &mut usize, -) -> Result { +) -> Result { let available = loop { match reader.fill_buf() { Ok([]) => return Ok(false), @@ -96,9 +90,11 @@ fn read_utf8_buffered( } match err.error_len() { - Some(_invalid_len) => Err(ReaderError::InvalidUtf8 { - value: available[valid_bytes], - }), + Some(_invalid_len) => Err(Error::reader( + "invalid UTF-8", + *offset, + available[valid_bytes] as _, + )), None => { if valid_bytes != 0 { // Some valid UTF-8 characters were present, and the @@ -128,7 +124,7 @@ fn read_utf8_char_unbuffered( out: &mut VecDeque, initial: u8, offset: &mut usize, -) -> Result<(), ReaderError> { +) -> Result<()> { let width = utf8_char_width(initial); let mut buffer = [0; 4]; reader.read_exact(&mut buffer[..width])?; @@ -143,7 +139,7 @@ fn read_utf8_char_unbuffered( } else { // Since we read the exact character width, the only // possible error here is invalid Unicode. - Err(ReaderError::InvalidUtf8 { value: buffer[0] }) + Err(Error::reader("invalid UTF-8", *offset, buffer[0] as _)) } } @@ -151,7 +147,7 @@ fn read_utf16_buffered( reader: &mut dyn BufRead, out: &mut VecDeque, offset: &mut usize, -) -> Result { +) -> Result { let available = loop { match reader.fill_buf() { Ok([]) => return Ok(false), @@ -206,7 +202,7 @@ fn read_utf16_char_unbuffered( reader: &mut dyn BufRead, out: &mut VecDeque, offset: &mut usize, -) -> Result<(), ReaderError> { +) -> Result<()> { let mut buffer = [0; 2]; reader.read_exact(&mut buffer)?; let first = if BIG_ENDIAN { @@ -229,9 +225,11 @@ fn read_utf16_char_unbuffered( *offset += 4; Ok(()) } - Some(Err(err)) => Err(ReaderError::InvalidUtf16 { - value: err.unpaired_surrogate(), - }), + Some(Err(err)) => Err(Error::reader( + "invalid UTF-16", + *offset, + err.unpaired_surrogate() as _, + )), None => unreachable!(), } } else { @@ -264,7 +262,7 @@ fn is_utf16_surrogate(value: u16) -> bool { matches!(value, 0xD800..=0xDFFF) } -fn push_char(out: &mut VecDeque, ch: char, offset: usize) -> Result<(), ReaderError> { +fn push_char(out: &mut VecDeque, ch: char, offset: usize) -> Result<()> { if !(ch == '\x09' || ch == '\x0A' || ch == '\x0D' @@ -274,16 +272,17 @@ fn push_char(out: &mut VecDeque, ch: char, offset: usize) -> Result<(), Re || ch >= '\u{E000}' && ch <= '\u{FFFD}' || ch >= '\u{10000}' && ch <= '\u{10FFFF}') { - return yaml_parser_set_reader_error("control characters are not allowed", offset, ch as _); + return Err(Error::reader( + "control characters are not allowed", + offset, + ch as _, + )); } out.push_back(ch); Ok(()) } -pub(crate) fn yaml_parser_update_buffer( - parser: &mut Scanner, - length: usize, -) -> Result<(), ReaderError> { +pub(crate) fn yaml_parser_update_buffer(parser: &mut Scanner, length: usize) -> Result<()> { let reader = parser.read_handler.as_deref_mut().expect("no read handler"); if parser.buffer.len() >= length { return Ok(()); @@ -319,7 +318,7 @@ pub(crate) fn yaml_parser_update_buffer( } if parser.offset >= (!0_usize).wrapping_div(2_usize) { - return yaml_parser_set_reader_error("input is too long", parser.offset, -1); + return Err(Error::reader("input is too long", parser.offset, -1)); } Ok(()) } diff --git a/src/scanner.rs b/src/scanner.rs index 01301d1..3996559 100644 --- a/src/scanner.rs +++ b/src/scanner.rs @@ -5,8 +5,7 @@ use alloc::string::String; use crate::macros::{is_blankz, is_break}; use crate::reader::yaml_parser_update_buffer; use crate::{ - Encoding, Mark, ReaderError, ScalarStyle, ScannerError, SimpleKey, Token, TokenData, - INPUT_BUFFER_SIZE, + Encoding, Error, Mark, Result, ScalarStyle, SimpleKey, Token, TokenData, INPUT_BUFFER_SIZE, }; const MAX_NUMBER_LENGTH: u64 = 9_u64; @@ -92,7 +91,7 @@ impl<'r> Scanner<'r> { self.encoding = encoding; } - fn cache(&mut self, length: usize) -> Result<(), ReaderError> { + fn cache(&mut self, length: usize) -> Result<()> { if self.buffer.len() >= length { Ok(()) } else { @@ -170,7 +169,7 @@ impl<'r> Scanner<'r> { /// corresponding to the input stream. The initial token has the type /// [`TokenData::StreamStart`] while the ending token has the type /// [`TokenData::StreamEnd`]. - pub fn scan(&mut self) -> Result { + pub fn scan(&mut self) -> Result { if self.stream_end_produced { return Ok(Token { data: TokenData::StreamEnd, @@ -194,7 +193,7 @@ impl<'r> Scanner<'r> { } /// Equivalent of the libyaml `PEEK_TOKEN` macro, used by the parser. - pub(crate) fn peek(&mut self) -> Result<&Token, ScannerError> { + pub(crate) fn peek(&mut self) -> Result<&Token> { if self.token_available { return Ok(self .tokens @@ -213,7 +212,7 @@ impl<'r> Scanner<'r> { } /// Equivalent of the libyaml `PEEK_TOKEN` macro, used by the parser. - pub(crate) fn peek_mut(&mut self) -> Result<&mut Token, ScannerError> { + pub(crate) fn peek_mut(&mut self) -> Result<&mut Token> { if self.token_available { return Ok(self .tokens @@ -250,16 +249,11 @@ impl<'r> Scanner<'r> { context: &'static str, context_mark: Mark, problem: &'static str, - ) -> Result { - Err(ScannerError::Problem { - context, - context_mark, - problem, - problem_mark: self.mark, - }) + ) -> Result { + Err(Error::scanner(context, context_mark, problem, self.mark)) } - pub(crate) fn fetch_more_tokens(&mut self) -> Result<(), ScannerError> { + pub(crate) fn fetch_more_tokens(&mut self) -> Result<()> { let mut need_more_tokens; loop { need_more_tokens = false; @@ -283,7 +277,7 @@ impl<'r> Scanner<'r> { Ok(()) } - fn fetch_next_token(&mut self) -> Result<(), ScannerError> { + fn fetch_next_token(&mut self) -> Result<()> { self.cache(1)?; if !self.stream_start_produced { self.fetch_stream_start(); @@ -394,7 +388,7 @@ impl<'r> Scanner<'r> { ) } - fn stale_simple_keys(&mut self) -> Result<(), ScannerError> { + fn stale_simple_keys(&mut self) -> Result<()> { for simple_key in &mut self.simple_keys { let mark = simple_key.mark; if simple_key.possible @@ -414,7 +408,7 @@ impl<'r> Scanner<'r> { Ok(()) } - fn save_simple_key(&mut self) -> Result<(), ScannerError> { + fn save_simple_key(&mut self) -> Result<()> { let required = self.flow_level == 0 && self.indent as u64 == self.mark.column; if self.simple_key_allowed { let simple_key = SimpleKey { @@ -429,7 +423,7 @@ impl<'r> Scanner<'r> { Ok(()) } - fn remove_simple_key(&mut self) -> Result<(), ScannerError> { + fn remove_simple_key(&mut self) -> Result<()> { let simple_key: &mut SimpleKey = self.simple_keys.last_mut().unwrap(); if simple_key.possible { let mark = simple_key.mark; @@ -445,7 +439,7 @@ impl<'r> Scanner<'r> { Ok(()) } - fn increase_flow_level(&mut self) -> Result<(), ScannerError> { + fn increase_flow_level(&mut self) -> Result<()> { let empty_simple_key = SimpleKey { possible: false, required: false, @@ -472,13 +466,7 @@ impl<'r> Scanner<'r> { } } - fn roll_indent( - &mut self, - column: i64, - number: i64, - data: TokenData, - mark: Mark, - ) -> Result<(), ScannerError> { + fn roll_indent(&mut self, column: i64, number: i64, data: TokenData, mark: Mark) -> Result<()> { if self.flow_level != 0 { return Ok(()); } @@ -541,7 +529,7 @@ impl<'r> Scanner<'r> { self.tokens.push_back(token); } - fn fetch_stream_end(&mut self) -> Result<(), ScannerError> { + fn fetch_stream_end(&mut self) -> Result<()> { if self.mark.column != 0_u64 { self.mark.column = 0_u64; self.mark.line += 1; @@ -558,7 +546,7 @@ impl<'r> Scanner<'r> { Ok(()) } - fn fetch_directive(&mut self) -> Result<(), ScannerError> { + fn fetch_directive(&mut self) -> Result<()> { self.unroll_indent(-1_i64); self.remove_simple_key()?; self.simple_key_allowed = false; @@ -567,7 +555,7 @@ impl<'r> Scanner<'r> { Ok(()) } - fn fetch_document_indicator(&mut self, data: TokenData) -> Result<(), ScannerError> { + fn fetch_document_indicator(&mut self, data: TokenData) -> Result<()> { self.unroll_indent(-1_i64); self.remove_simple_key()?; self.simple_key_allowed = false; @@ -586,7 +574,7 @@ impl<'r> Scanner<'r> { Ok(()) } - fn fetch_flow_collection_start(&mut self, data: TokenData) -> Result<(), ScannerError> { + fn fetch_flow_collection_start(&mut self, data: TokenData) -> Result<()> { self.save_simple_key()?; self.increase_flow_level()?; self.simple_key_allowed = true; @@ -602,7 +590,7 @@ impl<'r> Scanner<'r> { Ok(()) } - fn fetch_flow_collection_end(&mut self, data: TokenData) -> Result<(), ScannerError> { + fn fetch_flow_collection_end(&mut self, data: TokenData) -> Result<()> { self.remove_simple_key()?; self.decrease_flow_level(); self.simple_key_allowed = false; @@ -618,7 +606,7 @@ impl<'r> Scanner<'r> { Ok(()) } - fn fetch_flow_entry(&mut self) -> Result<(), ScannerError> { + fn fetch_flow_entry(&mut self) -> Result<()> { self.remove_simple_key()?; self.simple_key_allowed = true; let start_mark: Mark = self.mark; @@ -633,7 +621,7 @@ impl<'r> Scanner<'r> { Ok(()) } - fn fetch_block_entry(&mut self) -> Result<(), ScannerError> { + fn fetch_block_entry(&mut self) -> Result<()> { if self.flow_level == 0 { if !self.simple_key_allowed { return self.set_scanner_error( @@ -663,7 +651,7 @@ impl<'r> Scanner<'r> { Ok(()) } - fn fetch_key(&mut self) -> Result<(), ScannerError> { + fn fetch_key(&mut self) -> Result<()> { if self.flow_level == 0 { if !self.simple_key_allowed { return self.set_scanner_error( @@ -693,7 +681,7 @@ impl<'r> Scanner<'r> { Ok(()) } - fn fetch_value(&mut self) -> Result<(), ScannerError> { + fn fetch_value(&mut self) -> Result<()> { let simple_key: &mut SimpleKey = self.simple_keys.last_mut().unwrap(); if simple_key.possible { let token = Token { @@ -746,7 +734,7 @@ impl<'r> Scanner<'r> { Ok(()) } - fn fetch_anchor(&mut self, fetch_alias_instead_of_anchor: bool) -> Result<(), ScannerError> { + fn fetch_anchor(&mut self, fetch_alias_instead_of_anchor: bool) -> Result<()> { self.save_simple_key()?; self.simple_key_allowed = false; let token = self.scan_anchor(fetch_alias_instead_of_anchor)?; @@ -754,7 +742,7 @@ impl<'r> Scanner<'r> { Ok(()) } - fn fetch_tag(&mut self) -> Result<(), ScannerError> { + fn fetch_tag(&mut self) -> Result<()> { self.save_simple_key()?; self.simple_key_allowed = false; let token = self.scan_tag()?; @@ -762,7 +750,7 @@ impl<'r> Scanner<'r> { Ok(()) } - fn fetch_block_scalar(&mut self, literal: bool) -> Result<(), ScannerError> { + fn fetch_block_scalar(&mut self, literal: bool) -> Result<()> { self.remove_simple_key()?; self.simple_key_allowed = true; let token = self.scan_block_scalar(literal)?; @@ -770,7 +758,7 @@ impl<'r> Scanner<'r> { Ok(()) } - fn fetch_flow_scalar(&mut self, single: bool) -> Result<(), ScannerError> { + fn fetch_flow_scalar(&mut self, single: bool) -> Result<()> { self.save_simple_key()?; self.simple_key_allowed = false; let token = self.scan_flow_scalar(single)?; @@ -778,7 +766,7 @@ impl<'r> Scanner<'r> { Ok(()) } - fn fetch_plain_scalar(&mut self) -> Result<(), ScannerError> { + fn fetch_plain_scalar(&mut self) -> Result<()> { self.save_simple_key()?; self.simple_key_allowed = false; let token = self.scan_plain_scalar()?; @@ -786,7 +774,7 @@ impl<'r> Scanner<'r> { Ok(()) } - fn scan_to_next_token(&mut self) -> Result<(), ScannerError> { + fn scan_to_next_token(&mut self) -> Result<()> { loop { self.cache(1)?; if self.mark.column == 0 && IS_BOM!(self.buffer) { @@ -817,7 +805,7 @@ impl<'r> Scanner<'r> { Ok(()) } - fn scan_directive(&mut self) -> Result { + fn scan_directive(&mut self) -> Result { let end_mark: Mark; let mut major: i32 = 0; let mut minor: i32 = 0; @@ -882,7 +870,7 @@ impl<'r> Scanner<'r> { } } - fn scan_directive_name(&mut self, start_mark: Mark) -> Result { + fn scan_directive_name(&mut self, start_mark: Mark) -> Result { let mut string = String::new(); self.cache(1)?; @@ -916,7 +904,7 @@ impl<'r> Scanner<'r> { start_mark: Mark, major: &mut i32, minor: &mut i32, - ) -> Result<(), ScannerError> { + ) -> Result<()> { self.cache(1)?; while IS_BLANK!(self.buffer) { self.skip_char(); @@ -934,11 +922,7 @@ impl<'r> Scanner<'r> { self.scan_version_directive_number(start_mark, minor) } - fn scan_version_directive_number( - &mut self, - start_mark: Mark, - number: &mut i32, - ) -> Result<(), ScannerError> { + fn scan_version_directive_number(&mut self, start_mark: Mark, number: &mut i32) -> Result<()> { let mut value: i32 = 0; let mut length = 0; self.cache(1)?; @@ -967,10 +951,7 @@ impl<'r> Scanner<'r> { } // Returns (handle, prefix) - fn scan_tag_directive_value( - &mut self, - start_mark: Mark, - ) -> Result<(String, String), ScannerError> { + fn scan_tag_directive_value(&mut self, start_mark: Mark) -> Result<(String, String)> { self.cache(1)?; loop { @@ -1010,7 +991,7 @@ impl<'r> Scanner<'r> { } } - fn scan_anchor(&mut self, scan_alias_instead_of_anchor: bool) -> Result { + fn scan_anchor(&mut self, scan_alias_instead_of_anchor: bool) -> Result { let mut length: i32 = 0; let mut string = String::new(); @@ -1060,7 +1041,7 @@ impl<'r> Scanner<'r> { } } - fn scan_tag(&mut self) -> Result { + fn scan_tag(&mut self) -> Result { let mut handle; let mut suffix; @@ -1115,11 +1096,7 @@ impl<'r> Scanner<'r> { }) } - fn scan_tag_handle( - &mut self, - directive: bool, - start_mark: Mark, - ) -> Result { + fn scan_tag_handle(&mut self, directive: bool, start_mark: Mark) -> Result { let mut string = String::new(); self.cache(1)?; @@ -1162,7 +1139,7 @@ impl<'r> Scanner<'r> { directive: bool, head: Option<&str>, start_mark: Mark, - ) -> Result { + ) -> Result { let head = head.unwrap_or(""); let mut length = head.len(); let mut string = String::new(); @@ -1223,7 +1200,7 @@ impl<'r> Scanner<'r> { directive: bool, start_mark: Mark, string: &mut String, - ) -> Result<(), ScannerError> { + ) -> Result<()> { let mut width: i32 = 0; loop { self.cache(3)?; @@ -1289,7 +1266,7 @@ impl<'r> Scanner<'r> { Ok(()) } - fn scan_block_scalar(&mut self, literal: bool) -> Result { + fn scan_block_scalar(&mut self, literal: bool) -> Result { let mut end_mark: Mark; let mut string = String::new(); let mut leading_break = String::new(); @@ -1447,7 +1424,7 @@ impl<'r> Scanner<'r> { breaks: &mut String, start_mark: Mark, end_mark: &mut Mark, - ) -> Result<(), ScannerError> { + ) -> Result<()> { let mut max_indent: i32 = 0; *end_mark = self.mark; loop { @@ -1485,7 +1462,7 @@ impl<'r> Scanner<'r> { Ok(()) } - fn scan_flow_scalar(&mut self, single: bool) -> Result { + fn scan_flow_scalar(&mut self, single: bool) -> Result { let mut string = String::new(); let mut leading_break = String::new(); let mut trailing_breaks = String::new(); @@ -1718,7 +1695,7 @@ impl<'r> Scanner<'r> { }) } - fn scan_plain_scalar(&mut self) -> Result { + fn scan_plain_scalar(&mut self) -> Result { let mut end_mark: Mark; let mut string = String::new(); let mut leading_break = String::new(); @@ -1856,7 +1833,7 @@ impl<'r> Default for Scanner<'r> { } impl<'r> Iterator for Scanner<'r> { - type Item = Result; + type Item = Result; fn next(&mut self) -> Option { if self.stream_end_produced {