mod bool;
mod choice;
#[cfg(feature = "decimal")]
mod decimal;
mod dict;
mod ext;
mod ip;
mod number;
mod object;
mod steps;
mod string;
pub use self::bool::{BoolDecoder, bool};
pub use choice::{
Discriminate, EnumOf, Literal, Variant, Variants, discriminate, enum_of, literal, variant,
};
#[cfg(feature = "decimal")]
pub use decimal::{DecimalDecoder, decimal};
pub use dict::{Dict, dict};
pub use ext::{JsonDecoderExt, ListDecoder, Nullable};
pub use number::{F64Decoder, IntDecoder, Integer, SignedInteger, f64, i32, i64, u32, u64};
pub use object::{
Field, FieldSet, Object, OptionalField, PresenceField, Strict, field, object, optional_field,
presence_field,
};
#[cfg(feature = "url")]
pub use string::UrlDecoder;
#[cfg(feature = "uuid")]
pub use string::UuidDecoder;
pub use string::{Parse, StringDecoder, string};
use crate::decoder::Decoder;
use crate::issue::{Issue, Issues};
use crate::path::Path;
use crate::{codes, message_keys};
use serde_json::Value;
pub mod prelude {
#[cfg(feature = "decimal")]
pub use super::decimal;
pub use super::{
JsonDecoderExt, bool, dict, discriminate, enum_of, f64, field, from_str, i32, i64, literal,
object, optional_field, presence_field, string, u32, u64, variant,
};
pub use crate::{BoxDecoder, Decoder, Issue, Issues, Presence, lazy, one_of};
pub use serde_json::{Value, json};
}
static MISSING: Value = Value::Null;
pub fn missing() -> &'static Value {
&MISSING
}
pub fn is_missing(value: &Value) -> bool {
std::ptr::eq(value, &MISSING)
}
pub fn from_str<D: Decoder<Value>>(decoder: &D, text: &str) -> Result<D::Output, Issues> {
let value: Value = serde_json::from_str(text).map_err(|e| {
Issue::new(codes::INVALID_FORMAT)
.with_message_key(message_keys::INVALID_FORMAT_JSON)
.with_meta("line", e.line())
.with_meta("column", e.column())
})?;
decoder.decode(&value)
}
pub(crate) fn node_type(value: &Value) -> &'static str {
match value {
v if is_missing(v) => "missing",
Value::Null => "null",
Value::Bool(_) => "boolean",
Value::Number(_) => "number",
Value::String(_) => "string",
Value::Array(_) => "array",
Value::Object(_) => "object",
}
}
pub(crate) fn required(path: &Path<'_>) -> Issue {
Issue::at_path(path, codes::REQUIRED)
}
pub(crate) fn type_mismatch(path: &Path<'_>, expected: &'static str, found: &Value) -> Issue {
Issue::at_path(path, codes::TYPE_MISMATCH)
.with_meta("expected", expected)
.with_meta("actual", node_type(found))
}
pub(crate) fn unexpected(path: &Path<'_>, expected: &'static str, found: &Value) -> Issue {
if found.is_null() {
required(path)
} else {
type_mismatch(path, expected, found)
}
}