Skip to main content

alpaca_core/
integer.rs

1use serde::{Deserialize, Deserializer, Serializer, de};
2
3#[derive(Debug, Deserialize)]
4#[serde(untagged)]
5enum StringOrNumber {
6    String(String),
7    Number(serde_json::Number),
8}
9
10fn parse_u32<E>(value: StringOrNumber) -> Result<u32, E>
11where
12    E: de::Error,
13{
14    let raw = match value {
15        StringOrNumber::String(value) => value,
16        StringOrNumber::Number(value) => value.to_string(),
17    };
18
19    raw.parse::<u32>()
20        .map_err(|error| E::custom(format!("invalid integer value `{raw}`: {error}")))
21}
22
23pub fn deserialize_u32_from_string_or_number<'de, D>(deserializer: D) -> Result<u32, D::Error>
24where
25    D: Deserializer<'de>,
26{
27    parse_u32(StringOrNumber::deserialize(deserializer)?)
28}
29
30pub fn deserialize_option_u32_from_string_or_number<'de, D>(
31    deserializer: D,
32) -> Result<Option<u32>, D::Error>
33where
34    D: Deserializer<'de>,
35{
36    Option::<StringOrNumber>::deserialize(deserializer)?
37        .map(parse_u32)
38        .transpose()
39}
40
41pub mod string_contract {
42    use super::*;
43
44    pub fn serialize_u32<S>(value: &u32, serializer: S) -> Result<S::Ok, S::Error>
45    where
46        S: Serializer,
47    {
48        serializer.serialize_str(&value.to_string())
49    }
50
51    pub fn serialize_option_u32<S>(value: &Option<u32>, serializer: S) -> Result<S::Ok, S::Error>
52    where
53        S: Serializer,
54    {
55        match value {
56            Some(value) => serialize_u32(value, serializer),
57            None => serializer.serialize_none(),
58        }
59    }
60}