Skip to content

Instantly share code, notes, and snippets.

@TimoFreiberg
Created March 27, 2019 12:11
Show Gist options
  • Save TimoFreiberg/3228cf85b9e5a2eac70d39997b784057 to your computer and use it in GitHub Desktop.
Save TimoFreiberg/3228cf85b9e5a2eac70d39997b784057 to your computer and use it in GitHub Desktop.
Rust calamine DataType to String deserializer
use std::fmt;
use serde::de::{self, Visitor};
use serde::{Deserialize, Deserializer};
fn deserialize_datatype_as_optional_string<'de, D>(
deserializer: D,
) -> Result<Option<String>, D::Error>
where
D: Deserializer<'de>,
{
struct DataTypeVisitor;
impl<'de> Visitor<'de> for DataTypeVisitor {
type Value = Option<String>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("Excel datatype")
}
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: de::Error,
{
if value.is_empty() {
Ok(None)
} else {
Ok(Some(value.to_string()))
}
}
fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(Some(v.to_string()))
}
fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(Some(v.to_string()))
}
fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(Some(v.to_string()))
}
fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(Some(v.to_string()))
}
fn visit_none<E>(self) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(None)
}
fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: Deserializer<'de>,
{
let _ = deserializer;
println!("visit_some called??");
Ok(None)
}
}
deserializer.deserialize_map(DataTypeVisitor)
}
#[derive(Debug, Clone, Deserialize)]
struct Example {
#[serde(rename = "id header")]
id: String,
#[serde(
rename = "Optional field",
deserialize_with = "deserialize_datatype_as_optional_string",
default
)]
optional_field: Option<String>,
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment