Skip to main content

plugx_input/
error.rs

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
51/// Marker for APIs that intentionally never fail during serialization.
52pub type InputSerializeError = Infallible;