#![doc = include_str!("../README.md")]
#![allow(clippy::len_without_is_empty)]
mod default_error;
mod impls;
#[cfg(feature = "serde-cs")]
pub mod serde_cs;
#[cfg(feature = "serde_json")]
pub mod serde_json;
mod value;
pub use default_error::DefaultError;
pub use default_error::DefaultErrorContent;
extern crate self as deserr;
pub use deserr_internal::DeserializeFromValue;
pub use value::{IntoValue, Map, Sequence, Value, ValueKind, ValuePointer, ValuePointerRef};
use std::fmt::Debug;
pub trait DeserializeFromValue<E: DeserializeError>: Sized {
fn deserialize_from_value<V: IntoValue>(
value: Value<V>,
location: ValuePointerRef,
) -> Result<Self, E>;
}
pub fn deserialize<Ret, Val, E>(value: Val) -> Result<Ret, E>
where
Ret: DeserializeFromValue<E>,
Val: IntoValue,
E: DeserializeError,
{
Ret::deserialize_from_value(value.into_value(), ValuePointerRef::Origin)
}
pub trait MergeWithError<T>: Sized {
fn merge(self_: Option<Self>, other: T, merge_location: ValuePointerRef) -> Result<Self, Self>;
}
pub enum ErrorKind<'a, V: IntoValue> {
IncorrectValueKind {
actual: Value<V>,
accepted: &'a [ValueKind],
},
MissingField {
field: &'a str,
},
UnknownKey {
key: &'a str,
accepted: &'a [&'a str],
},
UnknownValue {
value: &'a str,
accepted: &'a [&'a str],
},
Unexpected {
msg: String,
},
}
pub trait DeserializeError: Sized + MergeWithError<Self> {
fn error<V: IntoValue>(
self_: Option<Self>,
error: ErrorKind<V>,
location: ValuePointerRef,
) -> Result<Self, Self>;
}
#[doc(hidden)]
pub enum FieldState<T> {
Missing,
Err,
Some(T),
}
impl<T> FieldState<T> {
pub fn is_missing(&self) -> bool {
matches!(self, FieldState::Missing)
}
#[track_caller]
pub fn unwrap(self) -> T {
match self {
FieldState::Some(x) => x,
_ => panic!("Unwrapping an empty field state"),
}
}
#[track_caller]
pub fn unwrap_or(self, value: T) -> T {
match self {
FieldState::Some(x) => x,
FieldState::Missing => value,
FieldState::Err => value,
}
}
#[track_caller]
pub fn ok_or<E>(self, err: E) -> Result<T, E> {
match self {
FieldState::Some(x) => Ok(x),
FieldState::Missing => Err(err),
FieldState::Err => Err(err),
}
}
pub fn map<U>(self, f: impl Fn(T) -> U) -> FieldState<U> {
match self {
FieldState::Some(x) => FieldState::Some(f(x)),
FieldState::Missing => FieldState::Missing,
FieldState::Err => FieldState::Err,
}
}
}
#[doc(hidden)]
pub fn take_result_content<T>(r: Result<T, T>) -> T {
match r {
Ok(x) => x,
Err(x) => x,
}
}