use std::fmt; use serde::de::{self, Error, Visitor}; pub(crate) fn deserialize_i32<'de, D>(d: D) -> std::result::Result where D: serde::Deserializer<'de>, { d.deserialize_string(I32Visitor) } pub(crate) fn deserialize_i32_newtype<'de, N: From, D>( d: D, ) -> std::result::Result where D: serde::Deserializer<'de>, { d.deserialize_string(I32Visitor).map(N::from) } pub(crate) fn deserialize_u32<'de, D>(d: D) -> std::result::Result where D: serde::Deserializer<'de>, { d.deserialize_string(U32Visitor) } struct I32Visitor; impl<'de> Visitor<'de> for I32Visitor { type Value = i32; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("an integer between -2^31 and 2^31") } fn visit_i8(self, value: i8) -> Result where E: de::Error, { Ok(i32::from(value)) } fn visit_i32(self, value: i32) -> Result where E: de::Error, { Ok(value) } fn visit_i64(self, value: i64) -> Result where E: de::Error, { use std::i32; if value >= i64::from(i32::MIN) && value <= i64::from(i32::MAX) { Ok(value as i32) } else { Err(E::custom(format!("i32 out of range: {}", value))) } } fn visit_str(self, v: &str) -> Result where E: Error, { if let Ok(value) = v.parse::() { Ok(value) } else { Err(E::custom(format!("str does not contains valid i32: {}", v))) } } fn visit_string(self, v: String) -> Result where E: Error, { if let Ok(value) = v.parse::() { Ok(value) } else { Err(E::custom(format!( "string does not contains valid i32: {}", v ))) } } // Similar for other methods: // - visit_i16 // - visit_u8 // - visit_u16 // - visit_u32 // - visit_u64 } struct U32Visitor; impl<'de> Visitor<'de> for U32Visitor { type Value = u32; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("an integer between -2^31 and 2^31") } fn visit_u8(self, value: u8) -> Result where E: de::Error, { Ok(u32::from(value)) } fn visit_u32(self, value: u32) -> Result where E: de::Error, { Ok(value) } fn visit_u64(self, value: u64) -> Result where E: de::Error, { use std::u32; if value >= u64::from(u32::MIN) && value <= u64::from(u32::MAX) { Ok(value as u32) } else { Err(E::custom(format!("i32 out of range: {}", value))) } } fn visit_str(self, v: &str) -> Result where E: Error, { if let Ok(value) = v.parse::() { Ok(value) } else { Err(E::custom(format!("str does not contains valid i32: {}", v))) } } fn visit_string(self, v: String) -> Result where E: Error, { if let Ok(value) = v.parse::() { Ok(value) } else { Err(E::custom(format!( "string does not contains valid i32: {}", v ))) } } // Similar for other methods: // - visit_i16 // - visit_u8 // - visit_u16 // - visit_u32 // - visit_u64 }