Skip to content

Instantly share code, notes, and snippets.

@juliarose
Created September 6, 2023 20:09
Show Gist options
  • Save juliarose/c9c966771b6fab3fa74ff12fc2fd70d7 to your computer and use it in GitHub Desktop.
Save juliarose/c9c966771b6fab3fa74ff12fc2fd70d7 to your computer and use it in GitHub Desktop.
use std::str::FromStr;
use std::marker::PhantomData;
use serde::de::{self, Visitor};
pub struct StringOrU32Visitor<T> {
marker: PhantomData<T>,
}
impl<T> StringOrU32Visitor<T> {
pub fn new() -> Self {
Self {
marker: PhantomData,
}
}
}
impl<'de, T> Visitor<'de> for StringOrU32Visitor<T>
where
T: TryFrom<u32> + std::str::FromStr,
<T as FromStr>::Err: std::fmt::Display,
<T as TryFrom<u32>>::Error: std::fmt::Display,
{
type Value = T;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("a string or integer")
}
fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
where
E: de::Error,
{
let value = u32::try_from(value)
.map_err(|_| serde::de::Error::invalid_value(de::Unexpected::Unsigned(value), &self))?;
T::try_from(value)
.map_err(|e| serde::de::Error::custom(e.to_string()))
}
fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
where
E: de::Error,
{
T::from_str(s)
.map_err(|e| serde::de::Error::custom(e.to_string()))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment