1use crate::position::InputPath;
7use std::convert::Infallible;
8use thiserror::Error;
9
10pub const EXPECTED_INPUT_TYPES: &str = "boolean, integer, float, string, list, or map";
12
13#[derive(Debug, Clone, PartialEq, Eq, Error)]
15pub enum DeserializeError {
16 #[error("{}", invalid_type_message(.path, .expected, .found))]
18 InvalidType {
19 path: InputPath,
20 expected: &'static str,
21 found: String,
22 },
23 #[error("{}", integer_out_of_range_message(.path, *.value))]
25 IntegerOutOfRange { path: InputPath, value: i128 },
26 #[error("{path}: invalid archived data: {message}")]
28 InvalidArchive { path: InputPath, message: String },
29}
30
31#[cfg(feature = "serde")]
33pub fn invalid_type(path: InputPath, found: impl Into<String>) -> DeserializeError {
34 DeserializeError::InvalidType {
35 path,
36 expected: EXPECTED_INPUT_TYPES,
37 found: found.into(),
38 }
39}
40
41fn invalid_type_message(path: &InputPath, expected: &str, found: &str) -> String {
42 if path.is_empty() {
43 format!("expected {expected}, found {found}")
44 } else {
45 format!("{path}: expected {expected}, found {found}")
46 }
47}
48
49fn integer_out_of_range_message(path: &InputPath, value: i128) -> String {
50 if path.is_empty() {
51 format!("integer {value} is out of range for isize")
52 } else {
53 format!("{path}: integer {value} is out of range for isize")
54 }
55}
56
57#[cfg(feature = "serde")]
59pub fn i128_to_isize(value: i128) -> Option<isize> {
60 value.try_into().ok()
61}
62
63pub type InputSerializeError = Infallible;