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