Skip to content

Instantly share code, notes, and snippets.

@keirlawson
Created October 23, 2019 22:10
Show Gist options
  • Save keirlawson/c87a78332683a9a8ada4bcbe951a2228 to your computer and use it in GitHub Desktop.
Save keirlawson/c87a78332683a9a8ada4bcbe951a2228 to your computer and use it in GitHub Desktop.
Deserialise unit as emtpy list
[package]
name = "desertest"
version = "0.1.0"
authors = ["Keir Lawson <[email protected]>"]
edition = "2018"
[dependencies]
serde = { version = "1.0", features = ["derive"] }
serde_yaml = "0.8"
use serde::{Serialize, Deserialize, de, de::{Visitor, SeqAccess}, Deserializer};
use std::fmt;
#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct Foo {
#[serde(deserialize_with = "deserialize_point_list")]
foo: Vec<Point>
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct Point {
x: i8,
y: i8,
}
struct PointVisitor;
impl<'de> Visitor<'de> for PointVisitor {
type Value = Vec<Point>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a list of points")
}
fn visit_unit<E>(self) -> Result<Self::Value, E>
where
E: de::Error,
{
println!("visiting unit");
Ok(Vec::new())
}
fn visit_seq<A>(self, seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
Deserialize::deserialize(de::value::SeqAccessDeserializer::new(seq))
}
}
fn deserialize_point_list<'de, D>(deserializer: D) -> Result<Vec<Point>, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_any(PointVisitor)
}
fn main() -> Result<(), serde_yaml::Error> {
let list = "
foo:
- x: 1
y: 2
- x: 3
y: 4
";
let no_list = "
foo:
";
let deserialized_point: Foo = serde_yaml::from_str(&no_list)?;
dbg!(deserialized_point);
Ok(())
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment