Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save sebastianconcept/156823b0efa32280a34e047a4101d854 to your computer and use it in GitHub Desktop.
Save sebastianconcept/156823b0efa32280a34e047a4101d854 to your computer and use it in GitHub Desktop.
Deserialize for enum, useful when CSV records map variants with content structurally different
use anyhow::Result;
use csv::{ReaderBuilder, Trim};
use serde::{de, Deserialize, Deserializer};
use std::fmt;
use std::path::Path;
fn main() -> Result<()> {
let file_path = Path::new("shapes.csv");
let mut reader = ReaderBuilder::new()
.has_headers(false)
.trim(Trim::All)
.delimiter(b',')
.from_path(file_path)?;
for result in reader.deserialize::<Shape>() {
let shape: Shape = result?;
println!("{:?}", shape);
}
Ok(())
}
#[derive(Debug)]
pub enum Shape {
Circle(f64),
Square(f64),
Triangle(f64, String),
}
impl<'de> Deserialize<'de> for Shape {
fn deserialize<D>(deserializer: D) -> Result<Shape, D::Error>
where
D: Deserializer<'de>,
{
struct ShapeVisitor;
impl<'de> de::Visitor<'de> for ShapeVisitor {
type Value = Shape;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a valid shape")
}
fn visit_seq<A>(self, mut seq: A) -> Result<Shape, A::Error>
where
A: de::SeqAccess<'de>,
{
let shape_type: String = seq
.next_element()?
.ok_or_else(|| de::Error::invalid_length(0, &self))?;
match shape_type.as_str() {
"circle" => {
let area: f64 = seq
.next_element()?
.ok_or_else(|| de::Error::invalid_length(1, &self))?;
Ok(Shape::Circle(area))
}
"square" => {
let area: f64 = seq
.next_element()?
.ok_or_else(|| de::Error::invalid_length(1, &self))?;
Ok(Shape::Square(area))
}
"triangle" => {
let area: f64 = seq
.next_element()?
.ok_or_else(|| de::Error::invalid_length(1, &self))?;
let color: String = seq
.next_element()?
.ok_or_else(|| de::Error::invalid_length(2, &self))?;
Ok(Shape::Triangle(area, color))
}
_ => Err(de::Error::unknown_variant(
&shape_type,
&["circle", "square", "triangle"],
)),
}
}
}
deserializer.deserialize_seq(ShapeVisitor)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment