use std::{error, fmt, fmt::Display, io, string};
use serde::de::{self, Unexpected};
use crate::Bson;
#[derive(Debug)]
#[non_exhaustive]
pub enum Error {
IoError(io::Error),
FromUtf8Error(string::FromUtf8Error),
UnrecognizedDocumentElementType {
key: String,
element_type: u8,
},
SyntaxError { message: String },
EndOfStream,
InvalidTimestamp(i64),
AmbiguousTimestamp(i64),
DeserializationError {
message: String,
},
}
impl From<io::Error> for Error {
fn from(err: io::Error) -> Error {
Error::IoError(err)
}
}
impl From<string::FromUtf8Error> for Error {
fn from(err: string::FromUtf8Error) -> Error {
Error::FromUtf8Error(err)
}
}
impl fmt::Display for Error {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
match *self {
Error::IoError(ref inner) => inner.fmt(fmt),
Error::FromUtf8Error(ref inner) => inner.fmt(fmt),
Error::UnrecognizedDocumentElementType {
ref key,
element_type,
} => write!(
fmt,
"unrecognized element type for key \"{}\": `{:#x}`",
key, element_type
),
Error::SyntaxError { ref message } => message.fmt(fmt),
Error::EndOfStream => fmt.write_str("end of stream"),
Error::DeserializationError { ref message } => message.fmt(fmt),
Error::InvalidTimestamp(ref i) => write!(fmt, "no such local time {}", i),
Error::AmbiguousTimestamp(ref i) => write!(fmt, "ambiguous local time {}", i),
}
}
}
impl error::Error for Error {
fn cause(&self) -> Option<&dyn error::Error> {
match *self {
Error::IoError(ref inner) => Some(inner),
Error::FromUtf8Error(ref inner) => Some(inner),
_ => None,
}
}
}
impl de::Error for Error {
fn custom<T: Display>(msg: T) -> Error {
Error::DeserializationError {
message: msg.to_string(),
}
}
}
pub type Result<T> = std::result::Result<T, Error>;
impl Bson {
pub(crate) fn as_unexpected(&self) -> Unexpected {
match self {
Bson::Array(_) => Unexpected::Seq,
Bson::Binary(b) => Unexpected::Bytes(b.bytes.as_slice()),
Bson::Boolean(b) => Unexpected::Bool(*b),
Bson::DbPointer(_) => Unexpected::Other("dbpointer"),
Bson::Document(_) => Unexpected::Map,
Bson::Double(f) => Unexpected::Float(*f),
Bson::Int32(i) => Unexpected::Signed(*i as i64),
Bson::Int64(i) => Unexpected::Signed(*i),
Bson::JavaScriptCode(_) => Unexpected::Other("javascript code"),
Bson::JavaScriptCodeWithScope(_) => Unexpected::Other("javascript code with scope"),
Bson::MaxKey => Unexpected::Other("maxkey"),
Bson::MinKey => Unexpected::Other("minkey"),
Bson::Null => Unexpected::Unit,
Bson::Undefined => Unexpected::Other("undefined"),
Bson::ObjectId(_) => Unexpected::Other("objectid"),
Bson::RegularExpression(_) => Unexpected::Other("regex"),
Bson::String(s) => Unexpected::Str(s.as_str()),
Bson::Symbol(_) => Unexpected::Other("symbol"),
Bson::Timestamp(_) => Unexpected::Other("timestamp"),
Bson::DateTime(_) => Unexpected::Other("datetime"),
Bson::Decimal128(_) => Unexpected::Other("decimal128"),
}
}
}