diff --git a/src/de/error.rs b/src/de/error.rs deleted file mode 100644 index 3794cc4dc..000000000 --- a/src/de/error.rs +++ /dev/null @@ -1,100 +0,0 @@ -use serde::de; -use std::{error::Error as StdError, fmt, io, str::Utf8Error, string::FromUtf8Error}; - -use crate::parse::Position; - -/// Deserialization result. -pub type Result = std::result::Result; - -#[derive(Clone, Debug, PartialEq)] -pub enum Error { - IoError(String), - Message(String), - Parser(ParseError, Position), -} - -#[derive(Clone, Debug, PartialEq)] -pub enum ParseError { - Base64Error(base64::DecodeError), - Eof, - ExpectedArray, - ExpectedArrayEnd, - ExpectedAttribute, - ExpectedAttributeEnd, - ExpectedBoolean, - ExpectedComma, - ExpectedEnum, - ExpectedChar, - ExpectedFloat, - ExpectedInteger, - ExpectedOption, - ExpectedOptionEnd, - ExpectedMap, - ExpectedMapColon, - ExpectedMapEnd, - ExpectedStruct, - ExpectedStructEnd, - ExpectedUnit, - ExpectedStructName, - ExpectedString, - ExpectedStringEnd, - ExpectedIdentifier, - - InvalidEscape(&'static str), - - IntegerOutOfBounds, - - NoSuchExtension(String), - - UnclosedBlockComment, - UnderscoreAtBeginning, - UnexpectedByte(char), - - Utf8Error(Utf8Error), - TrailingCharacters, - - #[doc(hidden)] - __NonExhaustive, -} - -impl fmt::Display for Error { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match *self { - Error::IoError(ref s) => write!(f, "{}", s), - Error::Message(ref s) => write!(f, "{}", s), - Error::Parser(_, pos) => write!(f, "{}: {}", pos, self), - } - } -} - -impl de::Error for Error { - fn custom(msg: T) -> Self { - Error::Message(msg.to_string()) - } -} - -impl StdError for Error {} - -impl From for ParseError { - fn from(e: Utf8Error) -> Self { - ParseError::Utf8Error(e) - } -} - -impl From for ParseError { - fn from(e: FromUtf8Error) -> Self { - ParseError::Utf8Error(e.utf8_error()) - } -} - -impl From for Error { - fn from(e: Utf8Error) -> Self { - Error::Parser(ParseError::Utf8Error(e), Position { line: 0, col: 0 }) - } -} - -impl From for Error { - fn from(e: io::Error) -> Self { - Error::IoError(e.to_string()) - } -} diff --git a/src/de/mod.rs b/src/de/mod.rs index 34080eef8..e3bf242a7 100644 --- a/src/de/mod.rs +++ b/src/de/mod.rs @@ -1,5 +1,5 @@ /// Deserialization module. -pub use self::error::{Error, ParseError, Result}; +pub use crate::error::{Error, ErrorCode, Result}; pub use crate::parse::Position; use serde::de::{self, DeserializeSeed, Deserializer as SerdeError, Visitor}; @@ -10,7 +10,6 @@ use self::tag::TagDeserializer; use crate::extensions::Extensions; use crate::parse::{AnyNum, Bytes, ParsedStr}; -mod error; mod id; mod tag; #[cfg(test)] @@ -88,7 +87,7 @@ impl<'de> Deserializer<'de> { if self.bytes.bytes().is_empty() { Ok(()) } else { - self.bytes.err(ParseError::TrailingCharacters) + self.bytes.err(ErrorCode::TrailingCharacters) } } @@ -179,7 +178,7 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { b'.' => self.deserialize_f64(visitor), b'"' | b'r' => self.deserialize_string(visitor), b'\'' => self.deserialize_char(visitor), - other => self.bytes.err(ParseError::UnexpectedByte(other as char)), + other => self.bytes.err(ErrorCode::UnexpectedByte(other as char)), } } @@ -320,7 +319,7 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { match res { Ok(byte_buf) => visitor.visit_byte_buf(byte_buf), - Err(err) => self.bytes.err(ParseError::Base64Error(err)), + Err(err) => self.bytes.err(ErrorCode::Base64Error(err)), } } @@ -345,10 +344,10 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { if self.bytes.consume(")") { Ok(v) } else { - self.bytes.err(ParseError::ExpectedOptionEnd) + self.bytes.err(ErrorCode::ExpectedOptionEnd) } } else { - self.bytes.err(ParseError::ExpectedOption) + self.bytes.err(ErrorCode::ExpectedOption) } } @@ -360,7 +359,7 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { if self.bytes.consume("()") { visitor.visit_unit() } else { - self.bytes.err(ParseError::ExpectedUnit) + self.bytes.err(ErrorCode::ExpectedUnit) } } @@ -395,10 +394,10 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { if self.bytes.consume(")") { Ok(value) } else { - self.bytes.err(ParseError::ExpectedStructEnd) + self.bytes.err(ErrorCode::ExpectedStructEnd) } } else { - self.bytes.err(ParseError::ExpectedStruct) + self.bytes.err(ErrorCode::ExpectedStruct) } } @@ -413,10 +412,10 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { if self.bytes.consume("]") { Ok(value) } else { - self.bytes.err(ParseError::ExpectedArrayEnd) + self.bytes.err(ErrorCode::ExpectedArrayEnd) } } else { - self.bytes.err(ParseError::ExpectedArray) + self.bytes.err(ErrorCode::ExpectedArray) } } @@ -431,10 +430,10 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { if self.bytes.consume(")") { Ok(value) } else { - self.bytes.err(ParseError::ExpectedArrayEnd) + self.bytes.err(ErrorCode::ExpectedArrayEnd) } } else { - self.bytes.err(ParseError::ExpectedArray) + self.bytes.err(ErrorCode::ExpectedArray) } } @@ -462,10 +461,10 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { if self.bytes.consume("}") { Ok(value) } else { - self.bytes.err(ParseError::ExpectedMapEnd) + self.bytes.err(ErrorCode::ExpectedMapEnd) } } else { - self.bytes.err(ParseError::ExpectedMap) + self.bytes.err(ErrorCode::ExpectedMap) } } @@ -489,10 +488,10 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { if self.bytes.consume(")") { Ok(value) } else { - self.bytes.err(ParseError::ExpectedStructEnd) + self.bytes.err(ErrorCode::ExpectedStructEnd) } } else { - self.bytes.err(ParseError::ExpectedStruct) + self.bytes.err(ErrorCode::ExpectedStruct) } } @@ -540,7 +539,7 @@ impl<'a, 'de> CommaSeparated<'a, 'de> { } } - fn err(&self, kind: ParseError) -> Result { + fn err(&self, kind: ErrorCode) -> Result { self.de.bytes.err(kind) } @@ -604,7 +603,7 @@ impl<'de, 'a> de::MapAccess<'de> for CommaSeparated<'a, 'de> { Ok(res) } else { - self.err(ParseError::ExpectedMapColon) + self.err(ErrorCode::ExpectedMapColon) } } } @@ -658,10 +657,10 @@ impl<'de, 'a> de::VariantAccess<'de> for Enum<'a, 'de> { if self.de.bytes.consume(")") { Ok(val) } else { - self.de.bytes.err(ParseError::ExpectedStructEnd) + self.de.bytes.err(ErrorCode::ExpectedStructEnd) } } else { - self.de.bytes.err(ParseError::ExpectedStruct) + self.de.bytes.err(ErrorCode::ExpectedStruct) } } diff --git a/src/de/tests.rs b/src/de/tests.rs index de3028495..f74b87b65 100644 --- a/src/de/tests.rs +++ b/src/de/tests.rs @@ -149,13 +149,16 @@ y: 2.0 // 2! ); } -fn err(kind: ParseError, line: usize, col: usize) -> Result { - Err(Error::Parser(kind, Position { line, col })) +fn err(kind: ErrorCode, line: usize, col: usize) -> Result { + Err(Error { + code: kind, + position: Position { line, col }, + }) } #[test] fn test_err_wrong_value() { - use self::ParseError::*; + use self::ErrorCode::*; use std::collections::HashMap; assert_eq!(from_str::("'c'"), err(ExpectedFloat, 1, 1)); @@ -204,7 +207,10 @@ fn forgot_apostrophes() { let de: Result<(i32, String)> = from_str("(4, \"Hello)"); assert!(match de { - Err(Error::Parser(ParseError::ExpectedStringEnd, _)) => true, + Err(Error { + code: ErrorCode::ExpectedStringEnd, + position: _, + }) => true, _ => false, }); } @@ -213,14 +219,14 @@ fn forgot_apostrophes() { fn expected_attribute() { let de: Result = from_str("#\"Hello\""); - assert_eq!(de, err(ParseError::ExpectedAttribute, 1, 2)); + assert_eq!(de, err(ErrorCode::ExpectedAttribute, 1, 2)); } #[test] fn expected_attribute_end() { let de: Result = from_str("#![enable(unwrap_newtypes) \"Hello\""); - assert_eq!(de, err(ParseError::ExpectedAttributeEnd, 1, 28)); + assert_eq!(de, err(ErrorCode::ExpectedAttributeEnd, 1, 28)); } #[test] @@ -229,7 +235,7 @@ fn invalid_attribute() { assert_eq!( de, - err(ParseError::NoSuchExtension("invalid".to_string()), 1, 18) + err(ErrorCode::NoSuchExtension("invalid".to_string()), 1, 18) ); } diff --git a/src/de/value.rs b/src/de/value.rs index e49fad9ab..a9ba017eb 100644 --- a/src/de/value.rs +++ b/src/de/value.rs @@ -229,11 +229,14 @@ mod tests { #[test] fn test_tuples_error() { - use crate::de::{Error, ParseError, Position}; + use crate::de::{Error, ErrorCode, Position}; assert_eq!( Value::from_str("Foo:").unwrap_err(), - Error::Parser(ParseError::TrailingCharacters, Position { col: 4, line: 1 }), + Error { + code: ErrorCode::TrailingCharacters, + position: Position { col: 4, line: 1 } + }, ); } diff --git a/src/error.rs b/src/error.rs new file mode 100644 index 000000000..494561df0 --- /dev/null +++ b/src/error.rs @@ -0,0 +1,161 @@ +use serde::{de, ser}; +use std::{error::Error as StdError, fmt, io, str::Utf8Error, string::FromUtf8Error}; + +pub use crate::parse::Position; + +/// This type represents all possible errors that can occur when +/// serializing or deserializing RON data. +#[derive(Clone, Debug, PartialEq)] +pub struct Error { + pub code: ErrorCode, + pub position: Position, +} + +pub type Result = std::result::Result; + +#[non_exhaustive] +#[derive(Clone, Debug, PartialEq)] +pub enum ErrorCode { + Io(String), + Message(String), + Base64Error(base64::DecodeError), + Eof, + ExpectedArray, + ExpectedArrayEnd, + ExpectedAttribute, + ExpectedAttributeEnd, + ExpectedBoolean, + ExpectedComma, + // ExpectedEnum, + ExpectedChar, + ExpectedFloat, + ExpectedInteger, + ExpectedOption, + ExpectedOptionEnd, + ExpectedMap, + ExpectedMapColon, + ExpectedMapEnd, + ExpectedStruct, + ExpectedStructEnd, + ExpectedUnit, + // ExpectedStructName, + ExpectedString, + ExpectedStringEnd, + ExpectedIdentifier, + + InvalidEscape(&'static str), + + IntegerOutOfBounds, + + NoSuchExtension(String), + + UnclosedBlockComment, + UnderscoreAtBeginning, + UnexpectedByte(char), + + Utf8Error(Utf8Error), + TrailingCharacters, +} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + if (self.position == Position { line: 0, col: 0 }) { + write!(f, "{}", self.code) + } else { + write!(f, "{}: {}", self.position, self.code) + } + } +} + +impl fmt::Display for ErrorCode { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match *self { + ErrorCode::Io(ref s) => f.write_str(s), + ErrorCode::Message(ref s) => f.write_str(s), + ErrorCode::Base64Error(ref e) => fmt::Display::fmt(e, f), + ErrorCode::Eof => f.write_str("Unexpected end of file"), + ErrorCode::ExpectedArray => f.write_str("Expected array"), + ErrorCode::ExpectedArrayEnd => f.write_str("Expected end of array"), + ErrorCode::ExpectedAttribute => f.write_str("Expected an enable attribute"), + ErrorCode::ExpectedAttributeEnd => { + f.write_str("Expected closing `)` and `]` after the attribute") + } + ErrorCode::ExpectedBoolean => f.write_str("Expected boolean"), + ErrorCode::ExpectedComma => f.write_str("Expected comma"), + // ErrorCode::ExpectedEnum => f.write_str("Expected enum"), + ErrorCode::ExpectedChar => f.write_str("Expected char"), + ErrorCode::ExpectedFloat => f.write_str("Expected float"), + ErrorCode::ExpectedInteger => f.write_str("Expected integer"), + ErrorCode::ExpectedOption => f.write_str("Expected option"), + ErrorCode::ExpectedOptionEnd => f.write_str("Expected end of option"), + ErrorCode::ExpectedMap => f.write_str("Expected map"), + ErrorCode::ExpectedMapColon => f.write_str("Expected colon"), + ErrorCode::ExpectedMapEnd => f.write_str("Expected end of map"), + ErrorCode::ExpectedStruct => f.write_str("Expected struct"), + ErrorCode::ExpectedStructEnd => f.write_str("Expected end of struct"), + ErrorCode::ExpectedUnit => f.write_str("Expected unit"), + // ErrorCode::ExpectedStructName => f.write_str("Expected struct name"), + ErrorCode::ExpectedString => f.write_str("Expected string"), + ErrorCode::ExpectedStringEnd => f.write_str("Expected string end"), + ErrorCode::ExpectedIdentifier => f.write_str("Expected identifier"), + ErrorCode::InvalidEscape(_) => f.write_str("Invalid escape sequence"), + ErrorCode::IntegerOutOfBounds => f.write_str("Integer is out of bounds"), + ErrorCode::NoSuchExtension(_) => f.write_str("No such RON extension"), + ErrorCode::Utf8Error(ref e) => fmt::Display::fmt(e, f), + ErrorCode::UnclosedBlockComment => f.write_str("Unclosed block comment"), + ErrorCode::UnderscoreAtBeginning => f.write_str("Found underscore at the beginning"), + ErrorCode::UnexpectedByte(_) => f.write_str("Unexpected byte"), + ErrorCode::TrailingCharacters => f.write_str("Non-whitespace trailing characters"), + } + } +} + +impl de::Error for Error { + fn custom(msg: T) -> Self { + Error { + code: ErrorCode::Message(msg.to_string()), + position: Position { line: 0, col: 0 }, + } + } +} + +impl ser::Error for Error { + fn custom(msg: T) -> Self { + Error { + code: ErrorCode::Message(msg.to_string()), + position: Position { line: 0, col: 0 }, + } + } +} + +impl StdError for Error {} + +impl From for ErrorCode { + fn from(e: Utf8Error) -> Self { + ErrorCode::Utf8Error(e) + } +} + +impl From for ErrorCode { + fn from(e: FromUtf8Error) -> Self { + ErrorCode::Utf8Error(e.utf8_error()) + } +} + +impl From for Error { + fn from(e: Utf8Error) -> Self { + Error { + code: ErrorCode::Utf8Error(e), + position: Position { line: 0, col: 0 }, + } + } +} + +impl From for Error { + fn from(e: io::Error) -> Self { + Error { + code: ErrorCode::Io(e.to_string()), + position: Position { line: 0, col: 0 }, + } + } +} diff --git a/src/lib.rs b/src/lib.rs index d5fed6d29..9d2d176bd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -58,9 +58,16 @@ Serializing / Deserializing is as simple as calling `to_string` / `from_str`. !*/ pub mod de; -pub mod extensions; pub mod ser; + +pub mod error; pub mod value; -pub use crate::value::Value; + +pub mod extensions; + +pub use de::{from_str, Deserializer}; +pub use error::{Error, Result}; +pub use ser::{to_string, Serializer}; +pub use value::{Map, Number, Value}; mod parse; diff --git a/src/parse.rs b/src/parse.rs index 959483645..69f0ed664 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -4,7 +4,7 @@ use std::{ str::{from_utf8, from_utf8_unchecked, FromStr}, }; -use crate::de::{Error, ParseError, Result}; +use crate::error::{Error, ErrorCode, Result}; use crate::extensions::Extensions; const DIGITS: &[u8] = b"0123456789ABCDEFabcdef_"; @@ -105,13 +105,13 @@ impl<'a> Bytes<'a> { let num_bytes = self.next_bytes_contained_in(DIGITS); if num_bytes == 0 { - return self.err(ParseError::ExpectedInteger); + return self.err(ErrorCode::ExpectedInteger); } let s = unsafe { from_utf8_unchecked(&self.bytes[0..num_bytes]) }; if s.as_bytes()[0] == b'_' { - return self.err(ParseError::UnderscoreAtBeginning); + return self.err(ErrorCode::UnderscoreAtBeginning); } fn calc_num( @@ -128,17 +128,17 @@ impl<'a> Bytes<'a> { } if num_acc.checked_mul_ext(base) { - return bytes.err(ParseError::IntegerOutOfBounds); + return bytes.err(ErrorCode::IntegerOutOfBounds); } let digit = bytes.decode_hex(byte)?; if digit >= base { - return bytes.err(ParseError::ExpectedInteger); + return bytes.err(ErrorCode::ExpectedInteger); } if f(&mut num_acc, digit) { - return bytes.err(ParseError::IntegerOutOfBounds); + return bytes.err(ErrorCode::IntegerOutOfBounds); } } @@ -245,7 +245,7 @@ impl<'a> Bytes<'a> { } else if self.consume("false") { Ok(false) } else { - self.err(ParseError::ExpectedBoolean) + self.err(ErrorCode::ExpectedBoolean) } } @@ -255,7 +255,7 @@ impl<'a> Bytes<'a> { pub fn char(&mut self) -> Result { if !self.consume("'") { - return self.err(ParseError::ExpectedChar); + return self.err(ErrorCode::ExpectedChar); } let c = self.peek_or_eof()?; @@ -272,15 +272,15 @@ impl<'a> Bytes<'a> { let pos: usize = self.bytes[..max] .iter() .position(|&x| x == b'\'') - .ok_or_else(|| self.error(ParseError::ExpectedChar))?; + .ok_or_else(|| self.error(ErrorCode::ExpectedChar))?; let s = from_utf8(&self.bytes[0..pos]).map_err(|e| self.error(e.into()))?; let mut chars = s.chars(); let first = chars .next() - .ok_or_else(|| self.error(ParseError::ExpectedChar))?; + .ok_or_else(|| self.error(ErrorCode::ExpectedChar))?; if chars.next().is_some() { - return self.err(ParseError::ExpectedChar); + return self.err(ErrorCode::ExpectedChar); } let _ = self.advance(pos); @@ -289,7 +289,7 @@ impl<'a> Bytes<'a> { }; if !self.consume("'") { - return self.err(ParseError::ExpectedChar); + return self.err(ErrorCode::ExpectedChar); } Ok(c) @@ -375,21 +375,21 @@ impl<'a> Bytes<'a> { Ok(peek) } - pub fn err(&self, kind: ParseError) -> Result { + pub fn err(&self, kind: ErrorCode) -> Result { Err(self.error(kind)) } - pub fn error(&self, kind: ParseError) -> Error { - Error::Parser( - kind, - Position { + pub fn error(&self, kind: ErrorCode) -> Error { + Error { + code: kind, + position: Position { line: self.line, col: self.column, }, - ) + } } - pub fn expect_byte(&mut self, byte: u8, error: ParseError) -> Result<()> { + pub fn expect_byte(&mut self, byte: u8, error: ErrorCode) -> Result<()> { self.eat_byte() .and_then(|b| if b == byte { Ok(()) } else { self.err(error) }) } @@ -401,7 +401,7 @@ impl<'a> Bytes<'a> { } if !self.consume_all(&["#", "!", "[", "enable", "("])? { - return self.err(ParseError::ExpectedAttribute); + return self.err(ErrorCode::ExpectedAttribute); } self.skip_ws()?; @@ -410,7 +410,7 @@ impl<'a> Bytes<'a> { loop { let ident = self.identifier()?; let extension = Extensions::from_ident(ident).ok_or_else(|| { - self.error(ParseError::NoSuchExtension( + self.error(ErrorCode::NoSuchExtension( from_utf8(ident).unwrap().to_owned(), )) })?; @@ -421,7 +421,7 @@ impl<'a> Bytes<'a> { // If we have no comma but another item, return an error if !comma && self.check_ident_char(0) { - return self.err(ParseError::ExpectedComma); + return self.err(ErrorCode::ExpectedComma); } // If there's no comma, assume the list ended. @@ -437,7 +437,7 @@ impl<'a> Bytes<'a> { if self.consume_all(&[")", "]"])? { Ok(extensions) } else { - Err(self.error(ParseError::ExpectedAttributeEnd)) + Err(self.error(ErrorCode::ExpectedAttributeEnd)) } } @@ -454,7 +454,7 @@ impl<'a> Bytes<'a> { let num_bytes = self.next_bytes_contained_in(FLOAT_CHARS); let s = unsafe { from_utf8_unchecked(&self.bytes[0..num_bytes]) }; - let res = FromStr::from_str(s).map_err(|_| self.error(ParseError::ExpectedFloat)); + let res = FromStr::from_str(s).map_err(|_| self.error(ErrorCode::ExpectedFloat)); let _ = self.advance(num_bytes); @@ -478,9 +478,9 @@ impl<'a> Bytes<'a> { let second = self .bytes .get(1) - .ok_or_else(|| self.error(ParseError::Eof))?; + .ok_or_else(|| self.error(ErrorCode::Eof))?; if *second == b'"' || *second == b'#' { - return self.err(ParseError::ExpectedIdentifier); + return self.err(ErrorCode::ExpectedIdentifier); } } @@ -488,7 +488,7 @@ impl<'a> Bytes<'a> { Ok(bytes) } else { - self.err(ParseError::ExpectedIdentifier) + self.err(ErrorCode::ExpectedIdentifier) } } @@ -543,7 +543,7 @@ impl<'a> Bytes<'a> { self.bytes .get(0) .cloned() - .ok_or_else(|| self.error(ParseError::Eof)) + .ok_or_else(|| self.error(ErrorCode::Eof)) } pub fn signed_integer(&mut self) -> Result @@ -571,7 +571,7 @@ impl<'a> Bytes<'a> { } else if self.consume("r") { self.raw_string() } else { - self.err(ParseError::ExpectedString) + self.err(ErrorCode::ExpectedString) } } @@ -583,7 +583,7 @@ impl<'a> Bytes<'a> { .iter() .enumerate() .find(|&(_, &b)| b == b'\\' || b == b'"') - .ok_or_else(|| self.error(ParseError::ExpectedStringEnd))?; + .ok_or_else(|| self.error(ErrorCode::ExpectedStringEnd))?; if *end_or_escape == b'"' { let s = from_utf8(&self.bytes[..i]).map_err(|e| self.error(e.into()))?; @@ -614,7 +614,7 @@ impl<'a> Bytes<'a> { .iter() .enumerate() .find(|&(_, &b)| b == b'\\' || b == b'"') - .ok_or(ParseError::Eof) + .ok_or(ErrorCode::Eof) .map_err(|e| self.error(e))?; i = new_i; @@ -636,7 +636,7 @@ impl<'a> Bytes<'a> { let _ = self.advance(num_hashes); if !self.consume("\"") { - return self.err(ParseError::ExpectedString); + return self.err(ErrorCode::ExpectedString); } let ending = [&[b'"'], hashes].concat(); @@ -644,7 +644,7 @@ impl<'a> Bytes<'a> { .bytes .windows(num_hashes + 1) .position(|window| window == ending.as_slice()) - .ok_or_else(|| self.error(ParseError::ExpectedStringEnd))?; + .ok_or_else(|| self.error(ErrorCode::ExpectedStringEnd))?; let s = from_utf8(&self.bytes[..i]).map_err(|e| self.error(e.into()))?; @@ -683,7 +683,7 @@ impl<'a> Bytes<'a> { c @ b'0'..=b'9' => Ok(c - b'0'), c @ b'a'..=b'f' => Ok(10 + c - b'a'), c @ b'A'..=b'F' => Ok(10 + c - b'A'), - _ => self.err(ParseError::InvalidEscape("Non-hex digit found")), + _ => self.err(ErrorCode::InvalidEscape("Non-hex digit found")), } } @@ -697,7 +697,7 @@ impl<'a> Bytes<'a> { b't' => '\t', b'x' => self.decode_ascii_escape()? as char, b'u' => { - self.expect_byte(b'{', ParseError::InvalidEscape("Missing {"))?; + self.expect_byte(b'{', ErrorCode::InvalidEscape("Missing {"))?; let mut bytes: u32 = 0; let mut num_digits = 0; @@ -719,17 +719,17 @@ impl<'a> Bytes<'a> { } if num_digits == 0 { - return self.err(ParseError::InvalidEscape( + return self.err(ErrorCode::InvalidEscape( "Expected 1-6 digits, got 0 digits", )); } - self.expect_byte(b'}', ParseError::InvalidEscape("No } at the end"))?; + self.expect_byte(b'}', ErrorCode::InvalidEscape("No } at the end"))?; char_from_u32(bytes) - .ok_or_else(|| self.error(ParseError::InvalidEscape("Not a valid char")))? + .ok_or_else(|| self.error(ErrorCode::InvalidEscape("Not a valid char")))? } _ => { - return self.err(ParseError::InvalidEscape("Unknown escape character")); + return self.err(ErrorCode::InvalidEscape("Unknown escape character")); } }; @@ -755,7 +755,7 @@ impl<'a> Bytes<'a> { .count(); if self.bytes.is_empty() { - return self.err(ParseError::UnclosedBlockComment); + return self.err(ErrorCode::UnclosedBlockComment); } let _ = self.advance(bytes); @@ -767,11 +767,11 @@ impl<'a> Bytes<'a> { level -= 1; } else { self.eat_byte() - .map_err(|_| self.error(ParseError::UnclosedBlockComment))?; + .map_err(|_| self.error(ErrorCode::UnclosedBlockComment))?; } } } - b => return self.err(ParseError::UnexpectedByte(b as char)), + b => return self.err(ErrorCode::UnexpectedByte(b as char)), } Ok(true) diff --git a/src/ser/mod.rs b/src/ser/mod.rs index 3bddba571..de180072c 100644 --- a/src/ser/mod.rs +++ b/src/ser/mod.rs @@ -1,9 +1,7 @@ use serde::{ser, Deserialize, Serialize}; -use std::{ - error::Error as StdError, - fmt::{Display, Formatter, Result as FmtResult, Write}, -}; +use std::fmt::Write; +use crate::error::{Error, Result}; use crate::extensions::Extensions; mod value; @@ -31,38 +29,6 @@ where Ok(s.output) } -/// Serialization result. -pub type Result = std::result::Result; - -/// Serialization error. -#[derive(Clone, Debug, PartialEq)] -pub enum Error { - /// A custom error emitted by a serialized value. - Message(String), -} - -impl Display for Error { - fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { - match *self { - Error::Message(ref e) => write!(f, "Custom message: {}", e), - } - } -} - -impl ser::Error for Error { - fn custom(msg: T) -> Self { - Error::Message(msg.to_string()) - } -} - -impl StdError for Error { - fn description(&self) -> &str { - match *self { - Error::Message(ref e) => e, - } - } -} - /// Pretty serializer state struct Pretty { indent: usize, diff --git a/tests/comments.rs b/tests/comments.rs index d49ef73cd..f5d6f73c1 100644 --- a/tests/comments.rs +++ b/tests/comments.rs @@ -1,4 +1,4 @@ -use ron::de::{from_str, Error as RonErr, ParseError, Position}; +use ron::de::{from_str, Error as RonErr, ErrorCode, Position}; #[test] fn test_simple() { @@ -44,9 +44,9 @@ fn test_unclosed() { \"THE VALUE (which is invalid)\" " ), - Err(RonErr::Parser( - ParseError::UnclosedBlockComment, - Position { col: 1, line: 9 } - )) + Err(RonErr { + code: ErrorCode::UnclosedBlockComment, + position: Position { col: 1, line: 9 } + }) ); } diff --git a/tests/preserve_sequence.rs b/tests/preserve_sequence.rs index 0b040e83b..02cf8d811 100644 --- a/tests/preserve_sequence.rs +++ b/tests/preserve_sequence.rs @@ -20,7 +20,7 @@ struct Nested { } fn read_original(source: &str) -> String { - source.to_string() + source.to_string().replace("\r\n", "\n") } fn make_roundtrip(source: &str) -> String { @@ -34,7 +34,8 @@ fn make_roundtrip(source: &str) -> String { let pretty = PrettyConfig::new() .with_depth_limit(3) .with_separate_tuple_members(true) - .with_enumerate_arrays(true); + .with_enumerate_arrays(true) + .with_new_line("\n".into()); to_string_pretty(&config, pretty).expect("Serialization failed") } diff --git a/tests/value.rs b/tests/value.rs index 05b155ff9..3e7ea8f04 100644 --- a/tests/value.rs +++ b/tests/value.rs @@ -67,14 +67,17 @@ fn seq() { #[test] fn unit() { - use ron::de::{Error, ParseError, Position}; + use ron::error::{Error, ErrorCode, Position}; assert_eq!("()".parse(), Ok(Value::Unit)); assert_eq!("Foo".parse(), Ok(Value::Unit)); assert_eq!( "".parse::(), - Err(Error::Parser(ParseError::Eof, Position { col: 1, line: 1 })) + Err(Error { + code: ErrorCode::Eof, + position: Position { col: 1, line: 1 } + }) ); }