Have ScanError::new
take a String
.
Internally, `ScanError` stores a `String`. Having `new` take a `&str` misleadingly indicates that it stores a `&str`. This commit changes `new` so that it takes a `String`, and adds a convenience method, `new_str` that takes a `&str` and allocates a `String` for it.
This commit is contained in:
parent
3b1dee5ef7
commit
cbba46fa72
2 changed files with 88 additions and 73 deletions
|
@ -348,7 +348,7 @@ impl<T: Iterator<Item = char>> Parser<T> {
|
||||||
let token = self.scanner.next();
|
let token = self.scanner.next();
|
||||||
match token {
|
match token {
|
||||||
None => match self.scanner.get_error() {
|
None => match self.scanner.get_error() {
|
||||||
None => Err(ScanError::new(self.scanner.mark(), "unexpected eof")),
|
None => Err(ScanError::new_str(self.scanner.mark(), "unexpected eof")),
|
||||||
Some(e) => Err(e),
|
Some(e) => Err(e),
|
||||||
},
|
},
|
||||||
Some(tok) => Ok(tok),
|
Some(tok) => Ok(tok),
|
||||||
|
@ -402,7 +402,10 @@ impl<T: Iterator<Item = char>> Parser<T> {
|
||||||
if !self.scanner.stream_started() {
|
if !self.scanner.stream_started() {
|
||||||
let (ev, mark) = self.next_event_impl()?;
|
let (ev, mark) = self.next_event_impl()?;
|
||||||
if ev != Event::StreamStart {
|
if ev != Event::StreamStart {
|
||||||
return Err(ScanError::new(mark, "did not find expected <stream-start>"));
|
return Err(ScanError::new_str(
|
||||||
|
mark,
|
||||||
|
"did not find expected <stream-start>",
|
||||||
|
));
|
||||||
}
|
}
|
||||||
recv.on_event(ev, mark);
|
recv.on_event(ev, mark);
|
||||||
}
|
}
|
||||||
|
@ -435,7 +438,7 @@ impl<T: Iterator<Item = char>> Parser<T> {
|
||||||
recv: &mut R,
|
recv: &mut R,
|
||||||
) -> Result<(), ScanError> {
|
) -> Result<(), ScanError> {
|
||||||
if first_ev != Event::DocumentStart {
|
if first_ev != Event::DocumentStart {
|
||||||
return Err(ScanError::new(
|
return Err(ScanError::new_str(
|
||||||
mark,
|
mark,
|
||||||
"did not find expected <document-start>",
|
"did not find expected <document-start>",
|
||||||
));
|
));
|
||||||
|
@ -561,7 +564,10 @@ impl<T: Iterator<Item = char>> Parser<T> {
|
||||||
self.skip();
|
self.skip();
|
||||||
Ok((Event::StreamStart, mark))
|
Ok((Event::StreamStart, mark))
|
||||||
}
|
}
|
||||||
Token(mark, _) => Err(ScanError::new(mark, "did not find expected <stream-start>")),
|
Token(mark, _) => Err(ScanError::new_str(
|
||||||
|
mark,
|
||||||
|
"did not find expected <stream-start>",
|
||||||
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -606,17 +612,17 @@ impl<T: Iterator<Item = char>> Parser<T> {
|
||||||
Token(mark, TokenType::VersionDirective(_, _)) => {
|
Token(mark, TokenType::VersionDirective(_, _)) => {
|
||||||
// XXX parsing with warning according to spec
|
// XXX parsing with warning according to spec
|
||||||
//if major != 1 || minor > 2 {
|
//if major != 1 || minor > 2 {
|
||||||
// return Err(ScanError::new(tok.0,
|
// return Err(ScanError::new_str(tok.0,
|
||||||
// "found incompatible YAML document"));
|
// "found incompatible YAML document"));
|
||||||
//}
|
//}
|
||||||
if version_directive_received {
|
if version_directive_received {
|
||||||
return Err(ScanError::new(*mark, "duplicate version directive"));
|
return Err(ScanError::new_str(*mark, "duplicate version directive"));
|
||||||
}
|
}
|
||||||
version_directive_received = true;
|
version_directive_received = true;
|
||||||
}
|
}
|
||||||
Token(mark, TokenType::TagDirective(handle, prefix)) => {
|
Token(mark, TokenType::TagDirective(handle, prefix)) => {
|
||||||
if tags.contains_key(handle) {
|
if tags.contains_key(handle) {
|
||||||
return Err(ScanError::new(*mark, "the TAG directive must only be given at most once per handle in the same document"));
|
return Err(ScanError::new_str(*mark, "the TAG directive must only be given at most once per handle in the same document"));
|
||||||
}
|
}
|
||||||
tags.insert(handle.to_string(), prefix.to_string());
|
tags.insert(handle.to_string(), prefix.to_string());
|
||||||
}
|
}
|
||||||
|
@ -637,7 +643,7 @@ impl<T: Iterator<Item = char>> Parser<T> {
|
||||||
self.skip();
|
self.skip();
|
||||||
Ok((Event::DocumentStart, mark))
|
Ok((Event::DocumentStart, mark))
|
||||||
}
|
}
|
||||||
Token(mark, _) => Err(ScanError::new(
|
Token(mark, _) => Err(ScanError::new_str(
|
||||||
mark,
|
mark,
|
||||||
"did not find expected <document start>",
|
"did not find expected <document start>",
|
||||||
)),
|
)),
|
||||||
|
@ -682,7 +688,7 @@ impl<T: Iterator<Item = char>> Parser<T> {
|
||||||
if let Token(mark, TokenType::VersionDirective(..) | TokenType::TagDirective(..)) =
|
if let Token(mark, TokenType::VersionDirective(..) | TokenType::TagDirective(..)) =
|
||||||
*self.peek_token()?
|
*self.peek_token()?
|
||||||
{
|
{
|
||||||
return Err(ScanError::new(
|
return Err(ScanError::new_str(
|
||||||
mark,
|
mark,
|
||||||
"missing explicit document end marker before directive",
|
"missing explicit document end marker before directive",
|
||||||
));
|
));
|
||||||
|
@ -696,7 +702,7 @@ impl<T: Iterator<Item = char>> Parser<T> {
|
||||||
fn register_anchor(&mut self, name: String, _: &Marker) -> usize {
|
fn register_anchor(&mut self, name: String, _: &Marker) -> usize {
|
||||||
// anchors can be overridden/reused
|
// anchors can be overridden/reused
|
||||||
// if self.anchors.contains_key(name) {
|
// if self.anchors.contains_key(name) {
|
||||||
// return Err(ScanError::new(*mark,
|
// return Err(ScanError::new_str(*mark,
|
||||||
// "while parsing anchor, found duplicated anchor"));
|
// "while parsing anchor, found duplicated anchor"));
|
||||||
// }
|
// }
|
||||||
let new_id = self.anchor_id_count;
|
let new_id = self.anchor_id_count;
|
||||||
|
@ -714,7 +720,7 @@ impl<T: Iterator<Item = char>> Parser<T> {
|
||||||
if let Token(mark, TokenType::Alias(name)) = self.fetch_token() {
|
if let Token(mark, TokenType::Alias(name)) = self.fetch_token() {
|
||||||
match self.anchors.get(&name) {
|
match self.anchors.get(&name) {
|
||||||
None => {
|
None => {
|
||||||
return Err(ScanError::new(
|
return Err(ScanError::new_str(
|
||||||
mark,
|
mark,
|
||||||
"while parsing node, found unknown anchor",
|
"while parsing node, found unknown anchor",
|
||||||
))
|
))
|
||||||
|
@ -788,7 +794,7 @@ impl<T: Iterator<Item = char>> Parser<T> {
|
||||||
self.pop_state();
|
self.pop_state();
|
||||||
Ok((Event::empty_scalar_with_anchor(anchor_id, tag), mark))
|
Ok((Event::empty_scalar_with_anchor(anchor_id, tag), mark))
|
||||||
}
|
}
|
||||||
Token(mark, _) => Err(ScanError::new(
|
Token(mark, _) => Err(ScanError::new_str(
|
||||||
mark,
|
mark,
|
||||||
"while parsing a node, did not find expected node content",
|
"while parsing a node, did not find expected node content",
|
||||||
)),
|
)),
|
||||||
|
@ -826,7 +832,7 @@ impl<T: Iterator<Item = char>> Parser<T> {
|
||||||
self.skip();
|
self.skip();
|
||||||
Ok((Event::MappingEnd, mark))
|
Ok((Event::MappingEnd, mark))
|
||||||
}
|
}
|
||||||
Token(mark, _) => Err(ScanError::new(
|
Token(mark, _) => Err(ScanError::new_str(
|
||||||
mark,
|
mark,
|
||||||
"while parsing a block mapping, did not find expected key",
|
"while parsing a block mapping, did not find expected key",
|
||||||
)),
|
)),
|
||||||
|
@ -868,7 +874,7 @@ impl<T: Iterator<Item = char>> Parser<T> {
|
||||||
if !first {
|
if !first {
|
||||||
match *self.peek_token()? {
|
match *self.peek_token()? {
|
||||||
Token(_, TokenType::FlowEntry) => self.skip(),
|
Token(_, TokenType::FlowEntry) => self.skip(),
|
||||||
Token(mark, _) => return Err(ScanError::new(
|
Token(mark, _) => return Err(ScanError::new_str(
|
||||||
mark,
|
mark,
|
||||||
"while parsing a flow mapping, did not find expected ',' or '}'",
|
"while parsing a flow mapping, did not find expected ',' or '}'",
|
||||||
)),
|
)),
|
||||||
|
@ -954,7 +960,7 @@ impl<T: Iterator<Item = char>> Parser<T> {
|
||||||
self.skip();
|
self.skip();
|
||||||
}
|
}
|
||||||
Token(mark, _) if !first => {
|
Token(mark, _) if !first => {
|
||||||
return Err(ScanError::new(
|
return Err(ScanError::new_str(
|
||||||
mark,
|
mark,
|
||||||
"while parsing a flow sequence, expected ',' or ']'",
|
"while parsing a flow sequence, expected ',' or ']'",
|
||||||
));
|
));
|
||||||
|
@ -1026,7 +1032,7 @@ impl<T: Iterator<Item = char>> Parser<T> {
|
||||||
self.parse_node(true, false)
|
self.parse_node(true, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Token(mark, _) => Err(ScanError::new(
|
Token(mark, _) => Err(ScanError::new_str(
|
||||||
mark,
|
mark,
|
||||||
"while parsing a block collection, did not find expected '-' indicator",
|
"while parsing a block collection, did not find expected '-' indicator",
|
||||||
)),
|
)),
|
||||||
|
@ -1112,7 +1118,7 @@ impl<T: Iterator<Item = char>> Parser<T> {
|
||||||
// If the handle is of the form "!foo!", this cannot be a local handle and we need
|
// If the handle is of the form "!foo!", this cannot be a local handle and we need
|
||||||
// to error.
|
// to error.
|
||||||
if handle.len() >= 2 && handle.starts_with('!') && handle.ends_with('!') {
|
if handle.len() >= 2 && handle.starts_with('!') && handle.ends_with('!') {
|
||||||
Err(ScanError::new(mark, "the handle wasn't declared"))
|
Err(ScanError::new_str(mark, "the handle wasn't declared"))
|
||||||
} else {
|
} else {
|
||||||
Ok(Tag {
|
Ok(Tag {
|
||||||
handle: handle.to_string(),
|
handle: handle.to_string(),
|
||||||
|
|
|
@ -88,7 +88,13 @@ pub struct ScanError {
|
||||||
impl ScanError {
|
impl ScanError {
|
||||||
/// Create a new error from a location and an error string.
|
/// Create a new error from a location and an error string.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new(loc: Marker, info: &str) -> ScanError {
|
pub fn new(loc: Marker, info: String) -> ScanError {
|
||||||
|
ScanError { mark: loc, info }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Convenience alias for string slices.
|
||||||
|
#[must_use]
|
||||||
|
pub fn new_str(loc: Marker, info: &str) -> ScanError {
|
||||||
ScanError {
|
ScanError {
|
||||||
mark: loc,
|
mark: loc,
|
||||||
info: info.to_owned(),
|
info: info.to_owned(),
|
||||||
|
@ -674,7 +680,7 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
||||||
self.fetch_document_indicator(TokenType::DocumentEnd)?;
|
self.fetch_document_indicator(TokenType::DocumentEnd)?;
|
||||||
self.skip_ws_to_eol(SkipTabs::Yes)?;
|
self.skip_ws_to_eol(SkipTabs::Yes)?;
|
||||||
if !is_breakz(self.ch()) {
|
if !is_breakz(self.ch()) {
|
||||||
return Err(ScanError::new(
|
return Err(ScanError::new_str(
|
||||||
self.mark,
|
self.mark,
|
||||||
"invalid content after document end marker",
|
"invalid content after document end marker",
|
||||||
));
|
));
|
||||||
|
@ -683,7 +689,7 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self.mark.col as isize) < self.indent {
|
if (self.mark.col as isize) < self.indent {
|
||||||
return Err(ScanError::new(self.mark, "invalid indentation"));
|
return Err(ScanError::new_str(self.mark, "invalid indentation"));
|
||||||
}
|
}
|
||||||
|
|
||||||
let c = self.buffer[0];
|
let c = self.buffer[0];
|
||||||
|
@ -720,7 +726,7 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
||||||
}
|
}
|
||||||
'%' | '@' | '`' => Err(ScanError::new(
|
'%' | '@' | '`' => Err(ScanError::new(
|
||||||
self.mark,
|
self.mark,
|
||||||
&format!("unexpected character: `{c}'"),
|
format!("unexpected character: `{c}'"),
|
||||||
)),
|
)),
|
||||||
_ => self.fetch_plain_scalar(),
|
_ => self.fetch_plain_scalar(),
|
||||||
}
|
}
|
||||||
|
@ -738,7 +744,7 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
||||||
self.fetch_more_tokens()?;
|
self.fetch_more_tokens()?;
|
||||||
}
|
}
|
||||||
let Some(t) = self.tokens.pop_front() else {
|
let Some(t) = self.tokens.pop_front() else {
|
||||||
return Err(ScanError::new(
|
return Err(ScanError::new_str(
|
||||||
self.mark,
|
self.mark,
|
||||||
"did not find expected next token",
|
"did not find expected next token",
|
||||||
));
|
));
|
||||||
|
@ -798,7 +804,7 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
||||||
&& (sk.mark.line < self.mark.line || sk.mark.index + 1024 < self.mark.index)
|
&& (sk.mark.line < self.mark.line || sk.mark.index + 1024 < self.mark.index)
|
||||||
{
|
{
|
||||||
if sk.required {
|
if sk.required {
|
||||||
return Err(ScanError::new(self.mark, "simple key expect ':'"));
|
return Err(ScanError::new_str(self.mark, "simple key expect ':'"));
|
||||||
}
|
}
|
||||||
sk.possible = false;
|
sk.possible = false;
|
||||||
}
|
}
|
||||||
|
@ -828,7 +834,7 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
||||||
self.skip_ws_to_eol(SkipTabs::Yes)?;
|
self.skip_ws_to_eol(SkipTabs::Yes)?;
|
||||||
// If we have content on that line with a tab, return an error.
|
// If we have content on that line with a tab, return an error.
|
||||||
if !is_breakz(self.ch()) {
|
if !is_breakz(self.ch()) {
|
||||||
return Err(ScanError::new(
|
return Err(ScanError::new_str(
|
||||||
self.mark,
|
self.mark,
|
||||||
"tabs disallowed within this context (block indentation)",
|
"tabs disallowed within this context (block indentation)",
|
||||||
));
|
));
|
||||||
|
@ -884,7 +890,7 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if need_whitespace {
|
if need_whitespace {
|
||||||
Err(ScanError::new(self.mark(), "expected whitespace"))
|
Err(ScanError::new_str(self.mark(), "expected whitespace"))
|
||||||
} else {
|
} else {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -906,7 +912,7 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
||||||
}
|
}
|
||||||
// YAML comments must be preceded by whitespace.
|
// YAML comments must be preceded by whitespace.
|
||||||
'#' if !encountered_tab && !has_yaml_ws => {
|
'#' if !encountered_tab && !has_yaml_ws => {
|
||||||
return Err(ScanError::new(
|
return Err(ScanError::new_str(
|
||||||
self.mark,
|
self.mark,
|
||||||
"comments must be separated from other tokens by whitespace",
|
"comments must be separated from other tokens by whitespace",
|
||||||
));
|
));
|
||||||
|
@ -944,7 +950,7 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
||||||
// had. If one was required, however, that was an error and we must propagate it.
|
// had. If one was required, however, that was an error and we must propagate it.
|
||||||
for sk in &mut self.simple_keys {
|
for sk in &mut self.simple_keys {
|
||||||
if sk.required && sk.possible {
|
if sk.required && sk.possible {
|
||||||
return Err(ScanError::new(self.mark, "simple key expected"));
|
return Err(ScanError::new_str(self.mark, "simple key expected"));
|
||||||
}
|
}
|
||||||
sk.possible = false;
|
sk.possible = false;
|
||||||
}
|
}
|
||||||
|
@ -991,7 +997,7 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
||||||
start_mark,
|
start_mark,
|
||||||
TokenType::TagDirective(String::new(), String::new()),
|
TokenType::TagDirective(String::new(), String::new()),
|
||||||
)
|
)
|
||||||
// return Err(ScanError::new(start_mark,
|
// return Err(ScanError::new_str(start_mark,
|
||||||
// "while scanning a directive, found unknown directive name"))
|
// "while scanning a directive, found unknown directive name"))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -999,7 +1005,7 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
||||||
self.skip_ws_to_eol(SkipTabs::Yes)?;
|
self.skip_ws_to_eol(SkipTabs::Yes)?;
|
||||||
|
|
||||||
if !is_breakz(self.ch()) {
|
if !is_breakz(self.ch()) {
|
||||||
return Err(ScanError::new(
|
return Err(ScanError::new_str(
|
||||||
start_mark,
|
start_mark,
|
||||||
"while scanning a directive, did not find expected comment or line break",
|
"while scanning a directive, did not find expected comment or line break",
|
||||||
));
|
));
|
||||||
|
@ -1022,7 +1028,7 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
||||||
let major = self.scan_version_directive_number(mark)?;
|
let major = self.scan_version_directive_number(mark)?;
|
||||||
|
|
||||||
if self.ch() != '.' {
|
if self.ch() != '.' {
|
||||||
return Err(ScanError::new(
|
return Err(ScanError::new_str(
|
||||||
*mark,
|
*mark,
|
||||||
"while scanning a YAML directive, did not find expected digit or '.' character",
|
"while scanning a YAML directive, did not find expected digit or '.' character",
|
||||||
));
|
));
|
||||||
|
@ -1043,14 +1049,14 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if string.is_empty() {
|
if string.is_empty() {
|
||||||
return Err(ScanError::new(
|
return Err(ScanError::new_str(
|
||||||
start_mark,
|
start_mark,
|
||||||
"while scanning a directive, could not find expected directive name",
|
"while scanning a directive, could not find expected directive name",
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
if !is_blank_or_breakz(self.ch()) {
|
if !is_blank_or_breakz(self.ch()) {
|
||||||
return Err(ScanError::new(
|
return Err(ScanError::new_str(
|
||||||
start_mark,
|
start_mark,
|
||||||
"while scanning a directive, found unexpected non-alphabetical character",
|
"while scanning a directive, found unexpected non-alphabetical character",
|
||||||
));
|
));
|
||||||
|
@ -1064,7 +1070,7 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
||||||
let mut length = 0usize;
|
let mut length = 0usize;
|
||||||
while let Some(digit) = self.look_ch().to_digit(10) {
|
while let Some(digit) = self.look_ch().to_digit(10) {
|
||||||
if length + 1 > 9 {
|
if length + 1 > 9 {
|
||||||
return Err(ScanError::new(
|
return Err(ScanError::new_str(
|
||||||
*mark,
|
*mark,
|
||||||
"while scanning a YAML directive, found extremely long version number",
|
"while scanning a YAML directive, found extremely long version number",
|
||||||
));
|
));
|
||||||
|
@ -1075,7 +1081,7 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if length == 0 {
|
if length == 0 {
|
||||||
return Err(ScanError::new(
|
return Err(ScanError::new_str(
|
||||||
*mark,
|
*mark,
|
||||||
"while scanning a YAML directive, did not find expected version number",
|
"while scanning a YAML directive, did not find expected version number",
|
||||||
));
|
));
|
||||||
|
@ -1103,7 +1109,7 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
||||||
if is_blank_or_breakz(self.ch()) {
|
if is_blank_or_breakz(self.ch()) {
|
||||||
Ok(Token(*mark, TokenType::TagDirective(handle, prefix)))
|
Ok(Token(*mark, TokenType::TagDirective(handle, prefix)))
|
||||||
} else {
|
} else {
|
||||||
Err(ScanError::new(
|
Err(ScanError::new_str(
|
||||||
*mark,
|
*mark,
|
||||||
"while scanning TAG, did not find expected whitespace or line break",
|
"while scanning TAG, did not find expected whitespace or line break",
|
||||||
))
|
))
|
||||||
|
@ -1154,7 +1160,7 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
||||||
// XXX: ex 7.2, an empty scalar can follow a secondary tag
|
// XXX: ex 7.2, an empty scalar can follow a secondary tag
|
||||||
Ok(Token(start_mark, TokenType::Tag(handle, suffix)))
|
Ok(Token(start_mark, TokenType::Tag(handle, suffix)))
|
||||||
} else {
|
} else {
|
||||||
Err(ScanError::new(
|
Err(ScanError::new_str(
|
||||||
start_mark,
|
start_mark,
|
||||||
"while scanning a tag, did not find expected whitespace or line break",
|
"while scanning a tag, did not find expected whitespace or line break",
|
||||||
))
|
))
|
||||||
|
@ -1164,7 +1170,7 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
||||||
fn scan_tag_handle(&mut self, directive: bool, mark: &Marker) -> Result<String, ScanError> {
|
fn scan_tag_handle(&mut self, directive: bool, mark: &Marker) -> Result<String, ScanError> {
|
||||||
let mut string = String::new();
|
let mut string = String::new();
|
||||||
if self.look_ch() != '!' {
|
if self.look_ch() != '!' {
|
||||||
return Err(ScanError::new(
|
return Err(ScanError::new_str(
|
||||||
*mark,
|
*mark,
|
||||||
"while scanning a tag, did not find expected '!'",
|
"while scanning a tag, did not find expected '!'",
|
||||||
));
|
));
|
||||||
|
@ -1186,7 +1192,7 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
||||||
// It's either the '!' tag or not really a tag handle. If it's a %TAG
|
// It's either the '!' tag or not really a tag handle. If it's a %TAG
|
||||||
// directive, it's an error. If it's a tag token, it must be a part of
|
// directive, it's an error. If it's a tag token, it must be a part of
|
||||||
// URI.
|
// URI.
|
||||||
return Err(ScanError::new(
|
return Err(ScanError::new_str(
|
||||||
*mark,
|
*mark,
|
||||||
"while parsing a tag directive, did not find expected '!'",
|
"while parsing a tag directive, did not find expected '!'",
|
||||||
));
|
));
|
||||||
|
@ -1208,7 +1214,10 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
||||||
self.skip_non_blank();
|
self.skip_non_blank();
|
||||||
} else if !is_tag_char(self.ch()) {
|
} else if !is_tag_char(self.ch()) {
|
||||||
// Otherwise, check if the first global tag character is valid.
|
// Otherwise, check if the first global tag character is valid.
|
||||||
return Err(ScanError::new(*start_mark, "invalid global tag character"));
|
return Err(ScanError::new_str(
|
||||||
|
*start_mark,
|
||||||
|
"invalid global tag character",
|
||||||
|
));
|
||||||
} else if self.ch() == '%' {
|
} else if self.ch() == '%' {
|
||||||
// If it is valid and an escape sequence, escape it.
|
// If it is valid and an escape sequence, escape it.
|
||||||
string.push(self.scan_uri_escapes(start_mark)?);
|
string.push(self.scan_uri_escapes(start_mark)?);
|
||||||
|
@ -1249,7 +1258,7 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.ch() != '>' {
|
if self.ch() != '>' {
|
||||||
return Err(ScanError::new(
|
return Err(ScanError::new_str(
|
||||||
*start_mark,
|
*start_mark,
|
||||||
"while scanning a verbatim tag, did not find the expected '>'",
|
"while scanning a verbatim tag, did not find the expected '>'",
|
||||||
));
|
));
|
||||||
|
@ -1288,7 +1297,7 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if length == 0 {
|
if length == 0 {
|
||||||
return Err(ScanError::new(
|
return Err(ScanError::new_str(
|
||||||
*mark,
|
*mark,
|
||||||
"while parsing a tag, did not find expected tag URI",
|
"while parsing a tag, did not find expected tag URI",
|
||||||
));
|
));
|
||||||
|
@ -1304,7 +1313,7 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
||||||
self.lookahead(3);
|
self.lookahead(3);
|
||||||
|
|
||||||
if !(self.ch() == '%' && is_hex(self.buffer[1]) && is_hex(self.buffer[2])) {
|
if !(self.ch() == '%' && is_hex(self.buffer[1]) && is_hex(self.buffer[2])) {
|
||||||
return Err(ScanError::new(
|
return Err(ScanError::new_str(
|
||||||
*mark,
|
*mark,
|
||||||
"while parsing a tag, did not find URI escaped octet",
|
"while parsing a tag, did not find URI escaped octet",
|
||||||
));
|
));
|
||||||
|
@ -1318,7 +1327,7 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
||||||
_ if octet & 0xF0 == 0xE0 => 3,
|
_ if octet & 0xF0 == 0xE0 => 3,
|
||||||
_ if octet & 0xF8 == 0xF0 => 4,
|
_ if octet & 0xF8 == 0xF0 => 4,
|
||||||
_ => {
|
_ => {
|
||||||
return Err(ScanError::new(
|
return Err(ScanError::new_str(
|
||||||
*mark,
|
*mark,
|
||||||
"while parsing a tag, found an incorrect leading UTF-8 octet",
|
"while parsing a tag, found an incorrect leading UTF-8 octet",
|
||||||
));
|
));
|
||||||
|
@ -1327,7 +1336,7 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
||||||
code = octet;
|
code = octet;
|
||||||
} else {
|
} else {
|
||||||
if octet & 0xc0 != 0x80 {
|
if octet & 0xc0 != 0x80 {
|
||||||
return Err(ScanError::new(
|
return Err(ScanError::new_str(
|
||||||
*mark,
|
*mark,
|
||||||
"while parsing a tag, found an incorrect trailing UTF-8 octet",
|
"while parsing a tag, found an incorrect trailing UTF-8 octet",
|
||||||
));
|
));
|
||||||
|
@ -1345,7 +1354,7 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
||||||
|
|
||||||
match char::from_u32(code) {
|
match char::from_u32(code) {
|
||||||
Some(ch) => Ok(ch),
|
Some(ch) => Ok(ch),
|
||||||
None => Err(ScanError::new(
|
None => Err(ScanError::new_str(
|
||||||
*mark,
|
*mark,
|
||||||
"while parsing a tag, found an invalid UTF-8 codepoint",
|
"while parsing a tag, found an invalid UTF-8 codepoint",
|
||||||
)),
|
)),
|
||||||
|
@ -1374,7 +1383,7 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if string.is_empty() {
|
if string.is_empty() {
|
||||||
return Err(ScanError::new(start_mark, "while scanning an anchor or alias, did not find expected alphabetic or numeric character"));
|
return Err(ScanError::new_str(start_mark, "while scanning an anchor or alias, did not find expected alphabetic or numeric character"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if alias {
|
if alias {
|
||||||
|
@ -1452,7 +1461,7 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
||||||
self.flow_level = self
|
self.flow_level = self
|
||||||
.flow_level
|
.flow_level
|
||||||
.checked_add(1)
|
.checked_add(1)
|
||||||
.ok_or_else(|| ScanError::new(self.mark, "recursion limit exceeded"))?;
|
.ok_or_else(|| ScanError::new_str(self.mark, "recursion limit exceeded"))?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1471,14 +1480,14 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
||||||
fn fetch_block_entry(&mut self) -> ScanResult {
|
fn fetch_block_entry(&mut self) -> ScanResult {
|
||||||
if self.flow_level > 0 {
|
if self.flow_level > 0 {
|
||||||
// - * only allowed in block
|
// - * only allowed in block
|
||||||
return Err(ScanError::new(
|
return Err(ScanError::new_str(
|
||||||
self.mark,
|
self.mark,
|
||||||
r#""-" is only valid inside a block"#,
|
r#""-" is only valid inside a block"#,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
// Check if we are allowed to start a new entry.
|
// Check if we are allowed to start a new entry.
|
||||||
if !self.simple_key_allowed {
|
if !self.simple_key_allowed {
|
||||||
return Err(ScanError::new(
|
return Err(ScanError::new_str(
|
||||||
self.mark,
|
self.mark,
|
||||||
"block sequence entries are not allowed in this context",
|
"block sequence entries are not allowed in this context",
|
||||||
));
|
));
|
||||||
|
@ -1487,7 +1496,7 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
||||||
// ???, fixes test G9HC.
|
// ???, fixes test G9HC.
|
||||||
if let Some(Token(mark, TokenType::Anchor(..) | TokenType::Tag(..))) = self.tokens.back() {
|
if let Some(Token(mark, TokenType::Anchor(..) | TokenType::Tag(..))) = self.tokens.back() {
|
||||||
if self.mark.col == 0 && mark.col == 0 && self.indent > -1 {
|
if self.mark.col == 0 && mark.col == 0 && self.indent > -1 {
|
||||||
return Err(ScanError::new(*mark, "invalid indentation for anchor"));
|
return Err(ScanError::new_str(*mark, "invalid indentation for anchor"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1500,7 +1509,7 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
||||||
let found_tabs = self.skip_ws_to_eol(SkipTabs::Yes)?.found_tabs();
|
let found_tabs = self.skip_ws_to_eol(SkipTabs::Yes)?.found_tabs();
|
||||||
self.lookahead(2);
|
self.lookahead(2);
|
||||||
if found_tabs && self.buffer[0] == '-' && is_blank_or_breakz(self.buffer[1]) {
|
if found_tabs && self.buffer[0] == '-' && is_blank_or_breakz(self.buffer[1]) {
|
||||||
return Err(ScanError::new(
|
return Err(ScanError::new_str(
|
||||||
self.mark,
|
self.mark,
|
||||||
"'-' must be followed by a valid YAML whitespace",
|
"'-' must be followed by a valid YAML whitespace",
|
||||||
));
|
));
|
||||||
|
@ -1574,7 +1583,7 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
||||||
self.skip_non_blank();
|
self.skip_non_blank();
|
||||||
if is_digit(self.look_ch()) {
|
if is_digit(self.look_ch()) {
|
||||||
if self.ch() == '0' {
|
if self.ch() == '0' {
|
||||||
return Err(ScanError::new(
|
return Err(ScanError::new_str(
|
||||||
start_mark,
|
start_mark,
|
||||||
"while scanning a block scalar, found an indentation indicator equal to 0",
|
"while scanning a block scalar, found an indentation indicator equal to 0",
|
||||||
));
|
));
|
||||||
|
@ -1584,7 +1593,7 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
||||||
}
|
}
|
||||||
} else if is_digit(self.ch()) {
|
} else if is_digit(self.ch()) {
|
||||||
if self.ch() == '0' {
|
if self.ch() == '0' {
|
||||||
return Err(ScanError::new(
|
return Err(ScanError::new_str(
|
||||||
start_mark,
|
start_mark,
|
||||||
"while scanning a block scalar, found an indentation indicator equal to 0",
|
"while scanning a block scalar, found an indentation indicator equal to 0",
|
||||||
));
|
));
|
||||||
|
@ -1607,7 +1616,7 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
||||||
|
|
||||||
// Check if we are at the end of the line.
|
// Check if we are at the end of the line.
|
||||||
if !is_breakz(self.look_ch()) {
|
if !is_breakz(self.look_ch()) {
|
||||||
return Err(ScanError::new(
|
return Err(ScanError::new_str(
|
||||||
start_mark,
|
start_mark,
|
||||||
"while scanning a block scalar, did not find expected comment or line break",
|
"while scanning a block scalar, did not find expected comment or line break",
|
||||||
));
|
));
|
||||||
|
@ -1619,7 +1628,7 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.look_ch() == '\t' {
|
if self.look_ch() == '\t' {
|
||||||
return Err(ScanError::new(
|
return Err(ScanError::new_str(
|
||||||
start_mark,
|
start_mark,
|
||||||
"a block scalar content cannot start with a tab",
|
"a block scalar content cannot start with a tab",
|
||||||
));
|
));
|
||||||
|
@ -1663,7 +1672,7 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.mark.col < indent && (self.mark.col as isize) > self.indent {
|
if self.mark.col < indent && (self.mark.col as isize) > self.indent {
|
||||||
return Err(ScanError::new(
|
return Err(ScanError::new_str(
|
||||||
self.mark,
|
self.mark,
|
||||||
"wrongly indented line in block scalar",
|
"wrongly indented line in block scalar",
|
||||||
));
|
));
|
||||||
|
@ -1891,21 +1900,21 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
||||||
&& (self.buffer[2] == '.')))
|
&& (self.buffer[2] == '.')))
|
||||||
&& is_blank_or_breakz(self.buffer[3])
|
&& is_blank_or_breakz(self.buffer[3])
|
||||||
{
|
{
|
||||||
return Err(ScanError::new(
|
return Err(ScanError::new_str(
|
||||||
start_mark,
|
start_mark,
|
||||||
"while scanning a quoted scalar, found unexpected document indicator",
|
"while scanning a quoted scalar, found unexpected document indicator",
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
if is_z(self.ch()) {
|
if is_z(self.ch()) {
|
||||||
return Err(ScanError::new(
|
return Err(ScanError::new_str(
|
||||||
start_mark,
|
start_mark,
|
||||||
"while scanning a quoted scalar, found unexpected end of stream",
|
"while scanning a quoted scalar, found unexpected end of stream",
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self.mark.col as isize) < self.indent {
|
if (self.mark.col as isize) < self.indent {
|
||||||
return Err(ScanError::new(
|
return Err(ScanError::new_str(
|
||||||
start_mark,
|
start_mark,
|
||||||
"invalid indentation in quoted scalar",
|
"invalid indentation in quoted scalar",
|
||||||
));
|
));
|
||||||
|
@ -1931,7 +1940,7 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
||||||
// Consume a space or a tab character.
|
// Consume a space or a tab character.
|
||||||
if leading_blanks {
|
if leading_blanks {
|
||||||
if self.ch() == '\t' && (self.mark.col as isize) < self.indent {
|
if self.ch() == '\t' && (self.mark.col as isize) < self.indent {
|
||||||
return Err(ScanError::new(
|
return Err(ScanError::new_str(
|
||||||
self.mark,
|
self.mark,
|
||||||
"tab cannot be used as indentation",
|
"tab cannot be used as indentation",
|
||||||
));
|
));
|
||||||
|
@ -1992,7 +2001,7 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
||||||
// Inside a flow context, this is allowed.
|
// Inside a flow context, this is allowed.
|
||||||
':' if self.flow_level > 0 => {}
|
':' if self.flow_level > 0 => {}
|
||||||
_ => {
|
_ => {
|
||||||
return Err(ScanError::new(
|
return Err(ScanError::new_str(
|
||||||
self.mark,
|
self.mark,
|
||||||
"invalid trailing content after double-quoted scalar",
|
"invalid trailing content after double-quoted scalar",
|
||||||
));
|
));
|
||||||
|
@ -2094,7 +2103,7 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
||||||
'u' => code_length = 4,
|
'u' => code_length = 4,
|
||||||
'U' => code_length = 8,
|
'U' => code_length = 8,
|
||||||
_ => {
|
_ => {
|
||||||
return Err(ScanError::new(
|
return Err(ScanError::new_str(
|
||||||
*start_mark,
|
*start_mark,
|
||||||
"while parsing a quoted scalar, found unknown escape character",
|
"while parsing a quoted scalar, found unknown escape character",
|
||||||
))
|
))
|
||||||
|
@ -2108,7 +2117,7 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
||||||
let mut value = 0u32;
|
let mut value = 0u32;
|
||||||
for i in 0..code_length {
|
for i in 0..code_length {
|
||||||
if !is_hex(self.buffer[i]) {
|
if !is_hex(self.buffer[i]) {
|
||||||
return Err(ScanError::new(
|
return Err(ScanError::new_str(
|
||||||
*start_mark,
|
*start_mark,
|
||||||
"while parsing a quoted scalar, did not find expected hexadecimal number",
|
"while parsing a quoted scalar, did not find expected hexadecimal number",
|
||||||
));
|
));
|
||||||
|
@ -2117,7 +2126,7 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let Some(ch) = char::from_u32(value) else {
|
let Some(ch) = char::from_u32(value) else {
|
||||||
return Err(ScanError::new(
|
return Err(ScanError::new_str(
|
||||||
*start_mark,
|
*start_mark,
|
||||||
"while parsing a quoted scalar, found invalid Unicode character escape code",
|
"while parsing a quoted scalar, found invalid Unicode character escape code",
|
||||||
));
|
));
|
||||||
|
@ -2150,7 +2159,7 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
||||||
let start_mark = self.mark;
|
let start_mark = self.mark;
|
||||||
|
|
||||||
if self.flow_level > 0 && (start_mark.col as isize) < indent {
|
if self.flow_level > 0 && (start_mark.col as isize) < indent {
|
||||||
return Err(ScanError::new(
|
return Err(ScanError::new_str(
|
||||||
start_mark,
|
start_mark,
|
||||||
"invalid indentation in flow construct",
|
"invalid indentation in flow construct",
|
||||||
));
|
));
|
||||||
|
@ -2168,7 +2177,7 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.flow_level > 0 && self.ch() == '-' && is_flow(self.buffer[1]) {
|
if self.flow_level > 0 && self.ch() == '-' && is_flow(self.buffer[1]) {
|
||||||
return Err(ScanError::new(
|
return Err(ScanError::new_str(
|
||||||
self.mark,
|
self.mark,
|
||||||
"plain scalar cannot start with '-' followed by ,[]{}",
|
"plain scalar cannot start with '-' followed by ,[]{}",
|
||||||
));
|
));
|
||||||
|
@ -2232,7 +2241,7 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
||||||
// empty. Skip to the end of the line.
|
// empty. Skip to the end of the line.
|
||||||
self.skip_ws_to_eol(SkipTabs::Yes)?;
|
self.skip_ws_to_eol(SkipTabs::Yes)?;
|
||||||
if !is_breakz(self.ch()) {
|
if !is_breakz(self.ch()) {
|
||||||
return Err(ScanError::new(
|
return Err(ScanError::new_str(
|
||||||
start_mark,
|
start_mark,
|
||||||
"while scanning a plain scalar, found a tab",
|
"while scanning a plain scalar, found a tab",
|
||||||
));
|
));
|
||||||
|
@ -2274,7 +2283,7 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
||||||
if self.flow_level == 0 {
|
if self.flow_level == 0 {
|
||||||
// Check if we are allowed to start a new key (not necessarily simple).
|
// Check if we are allowed to start a new key (not necessarily simple).
|
||||||
if !self.simple_key_allowed {
|
if !self.simple_key_allowed {
|
||||||
return Err(ScanError::new(
|
return Err(ScanError::new_str(
|
||||||
self.mark,
|
self.mark,
|
||||||
"mapping keys are not allowed in this context",
|
"mapping keys are not allowed in this context",
|
||||||
));
|
));
|
||||||
|
@ -2301,7 +2310,7 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
||||||
self.skip_non_blank();
|
self.skip_non_blank();
|
||||||
self.skip_yaml_whitespace()?;
|
self.skip_yaml_whitespace()?;
|
||||||
if self.ch() == '\t' {
|
if self.ch() == '\t' {
|
||||||
return Err(ScanError::new(
|
return Err(ScanError::new_str(
|
||||||
self.mark(),
|
self.mark(),
|
||||||
"tabs disallowed in this context",
|
"tabs disallowed in this context",
|
||||||
));
|
));
|
||||||
|
@ -2322,7 +2331,7 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
||||||
&& !self.skip_ws_to_eol(SkipTabs::Yes)?.has_valid_yaml_ws()
|
&& !self.skip_ws_to_eol(SkipTabs::Yes)?.has_valid_yaml_ws()
|
||||||
&& (self.ch() == '-' || is_alpha(self.ch()))
|
&& (self.ch() == '-' || is_alpha(self.ch()))
|
||||||
{
|
{
|
||||||
return Err(ScanError::new(
|
return Err(ScanError::new_str(
|
||||||
self.mark,
|
self.mark,
|
||||||
"':' must be followed by a valid YAML whitespace",
|
"':' must be followed by a valid YAML whitespace",
|
||||||
));
|
));
|
||||||
|
@ -2334,7 +2343,7 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
||||||
self.insert_token(sk.token_number - self.tokens_parsed, tok);
|
self.insert_token(sk.token_number - self.tokens_parsed, tok);
|
||||||
if self.implicit_flow_mapping {
|
if self.implicit_flow_mapping {
|
||||||
if sk.mark.line < start_mark.line {
|
if sk.mark.line < start_mark.line {
|
||||||
return Err(ScanError::new(
|
return Err(ScanError::new_str(
|
||||||
start_mark,
|
start_mark,
|
||||||
"illegal placement of ':' indicator",
|
"illegal placement of ':' indicator",
|
||||||
));
|
));
|
||||||
|
@ -2364,7 +2373,7 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
||||||
// The ':' indicator follows a complex key.
|
// The ':' indicator follows a complex key.
|
||||||
if self.flow_level == 0 {
|
if self.flow_level == 0 {
|
||||||
if !self.simple_key_allowed {
|
if !self.simple_key_allowed {
|
||||||
return Err(ScanError::new(
|
return Err(ScanError::new_str(
|
||||||
start_mark,
|
start_mark,
|
||||||
"mapping values are not allowed in this context",
|
"mapping values are not allowed in this context",
|
||||||
));
|
));
|
||||||
|
@ -2489,7 +2498,7 @@ impl<T: Iterator<Item = char>> Scanner<T> {
|
||||||
fn remove_simple_key(&mut self) -> ScanResult {
|
fn remove_simple_key(&mut self) -> ScanResult {
|
||||||
let last = self.simple_keys.last_mut().unwrap();
|
let last = self.simple_keys.last_mut().unwrap();
|
||||||
if last.possible && last.required {
|
if last.possible && last.required {
|
||||||
return Err(ScanError::new(self.mark, "simple key expected"));
|
return Err(ScanError::new_str(self.mark, "simple key expected"));
|
||||||
}
|
}
|
||||||
|
|
||||||
last.possible = false;
|
last.possible = false;
|
||||||
|
|
Loading…
Reference in a new issue