use num::bigint::BigInt; use std::convert::From; use crate::value::IOValue; #[derive(Debug)] pub enum Error { Io(std::io::Error), Message(String), InvalidUnicodeScalar(u32), NumberOutOfRange(BigInt), CannotDeserializeAny, MissingCloseDelimiter, MissingItem, Expected(ExpectedKind, Received), StreamingSerializationUnsupported, } #[derive(Debug)] pub enum Received { ReceivedSomethingElse, ReceivedRecordWithLabel(String), ReceivedOtherValue(IOValue), } #[derive(Debug, PartialEq)] pub enum ExpectedKind { Boolean, Float, Double, SignedIntegerI128, SignedIntegerU128, SignedInteger, String, ByteString, Symbol, Record(Option), SimpleRecord(String, Option), Sequence, Set, Dictionary, Embedded, SequenceOrSet, // Because of hacking up serde's data model: see open_sequence_or_set etc. Option, UnicodeScalar, } impl From for Error { fn from(e: std::io::Error) -> Self { Error::Io(e) } } impl From for std::io::Error { fn from(e: Error) -> Self { match e { Error::Io(ioe) => ioe, Error::Message(str) => std::io::Error::new(std::io::ErrorKind::Other, str), _ => std::io::Error::new(std::io::ErrorKind::Other, e.to_string()), } } } impl serde::ser::Error for Error { fn custom(msg: T) -> Self { Self::Message(msg.to_string()) } } impl serde::de::Error for Error { fn custom(msg: T) -> Self { Self::Message(msg.to_string()) } } impl std::error::Error for Error {} impl std::fmt::Display for Error { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{:?}", self) } } //--------------------------------------------------------------------------- pub fn is_io_error(e: &Error) -> bool { matches!(e, Error::Io(_)) } pub fn eof() -> Error { Error::Io(io_eof()) } pub fn is_eof_error(e: &Error) -> bool { if let Error::Io(ioe) = e { is_eof_io_error(ioe) } else { false } } pub fn syntax_error(s: &str) -> Error { Error::Io(io_syntax_error(s)) } pub fn is_syntax_error(e: &Error) -> bool { if let Error::Io(ioe) = e { is_syntax_io_error(ioe) } else { false } } //--------------------------------------------------------------------------- pub fn io_eof() -> std::io::Error { std::io::Error::new(std::io::ErrorKind::UnexpectedEof, "EOF") } pub fn is_eof_io_error(e: &std::io::Error) -> bool { matches!(e.kind(), std::io::ErrorKind::UnexpectedEof) } pub fn io_syntax_error(s: &str) -> std::io::Error { std::io::Error::new(std::io::ErrorKind::InvalidData, s) } pub fn is_syntax_io_error(e: &std::io::Error) -> bool { matches!(e.kind(), std::io::ErrorKind::InvalidData) }