Add function to deserialize numbers and strings as an integer

This commit is contained in:
Alejandro Domínguez 2020-11-20 00:36:51 +01:00 committed by Jonas Platte
parent d809066c9c
commit 0ac2f401f8

View File

@ -1,6 +1,11 @@
//! De-/serialization helpers for other ruma crates //! De-/serialization helpers for other ruma crates
use serde::de::{Deserialize, IntoDeserializer}; use js_int::Int;
use serde::{
de::{Error, IntoDeserializer},
Deserialize,
};
use std::convert::{TryFrom, TryInto};
pub mod can_be_empty; pub mod can_be_empty;
mod canonical_json; mod canonical_json;
@ -65,3 +70,33 @@ where
Some(s) => T::deserialize(s.into_deserializer()).map(Some), Some(s) => T::deserialize(s.into_deserializer()).map(Some),
} }
} }
// Helper type for deserialize_int_or_string_to_int
#[derive(Deserialize)]
#[serde(untagged)]
enum IntOrString<'a> {
Num(Int),
Str(&'a str),
}
impl TryFrom<IntOrString<'_>> for Int {
type Error = js_int::ParseIntError;
fn try_from(input: IntOrString) -> Result<Self, Self::Error> {
match input {
IntOrString::Num(n) => Ok(n),
IntOrString::Str(string) => string.parse(),
}
}
}
/// Take either an integer number or a string and deserialize to an integer number.
///
/// To be used like this:
/// `#[serde(deserialize_with = "int_or_string_to_int")]`
pub fn int_or_string_to_int<'de, D>(de: D) -> Result<Int, D::Error>
where
D: serde::Deserializer<'de>,
{
IntOrString::deserialize(de)?.try_into().map_err(D::Error::custom)
}