## My issue I want to deserialize data into Rust types using serde. The data format already exists and I want to remain compatible. It is currently JSON, but I want to specify deserializers independently of the format (so that later I can use eg. YAML). My file format is documented here: https://yalis.fr/git/yves/pyruse/src/branch/master/doc/conffile.md In module `common`, I have: ```rust #[derive(Clone, Debug, Eq, PartialEq)] pub enum Value { Bool(bool), Str(String), Int(isize), Date(DateTime), Map(HashMap), List(Vec) } ``` NOTE: No data from the file will ever become a `Date` variant. In module `modules`, I have: ```rust pub type ModuleArgs = HashMap; ``` The deserialization process is programmed in the `config` module. Here is what I first described: ```rust pub struct Config { actions: Vec, options: HashMap } pub struct Chain { name: String, steps: Vec } pub struct Step { module_name: String, args: ModuleArgs, then_dest: Option, else_dest: Option } ``` (Subsidiary question: If `args` above is not specified in the file, is it OK to want the `args` field to be an empty Hashmap, or is it worth the extra work to make it an `Option`?) I tried to follow the documentation, and misc. web pages, and ended up with that, so far: ```rust use serde::de::{self,Deserializer,MapAccess,SeqAccess,Visitor}; use serde::Deserialize; use std::collections::HashMap; use std::fmt; use crate::common::Value; use crate::modules::ModuleArgs; #[derive(Deserialize)] pub struct Config { actions: Vec, #[serde(flatten)] options: HashMap } pub struct Chain { name: String, steps: Vec } pub struct Step { module_name: String, args: ModuleArgs, then_dest: Option, else_dest: Option } struct ValueVisitor; impl<'de> Visitor<'de> for ValueVisitor { type Value = Value; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("a boolean, string, integer, array or object") } fn visit_bool(self, v: bool) -> Result where E: de::Error { Ok(Value::Bool(v)) } fn visit_i8(self, v: i8) -> Result where E: de::Error { Ok(Value::Int(v as isize)) } // … and so on … fn visit_u8(self, v: u8) -> Result where E: de::Error { Ok(Value::Int(v as isize)) } // … and so on … fn visit_f32(self, v: f32) -> Result where E: de::Error { Ok(Value::Int(v as isize)) } // … and so on … fn visit_char(self, v: char) -> Result where E: de::Error { Ok(Value::Str(v.to_string())) } // … and so on … fn visit_bytes(self, v: &[u8]) -> Result where E: de::Error { Ok(Value::Str(std::str::from_utf8(v).expect("Strings in the configuration must be UTF-8").to_string())) } // … and so on … fn visit_seq(self, seq: A) -> Result where A: SeqAccess<'de> { let list = Vec::with_capacity(seq.size_hint().unwrap_or(0)); while let Some(v) = seq.next_element()? { list.append(v); } Ok(Value::List(list)) } fn visit_map(self, map: A) -> Result where A: MapAccess<'de> { let map = HashMap::with_capacity(map.size_hint().unwrap_or(0)); while let Some((k, v)) = map.next_entry()? { map.insert(k, v); } Ok(Value::Map(map)) } } impl<'de> Deserialize<'de> for Value { fn deserialize(deserializer: D) -> Result where D: Deserializer<'de> { deserializer.deserialize_any(ValueVisitor) } } ``` And here, I’m stuck… 1. Both recursive visitors (`visit_seq` and `visit_map`) fail to compile. Basically, I just cannot find anywhere on the Internet how to deserialize a sub-structure from a Visitor… Here is the documentation I found, where I try to find inspiration: * https://serde.rs/impl-deserialize.html (obviously) * https://serde.rs/enum-representations.html * https://github.com/serde-rs/json/issues/144 * https://github.com/serde-rs/serde/issues/1470 * https://github.com/serde-rs/serde/issues/1131 * https://github.com/serde-rs/serde/issues/1364 * https://stackoverflow.com/a/48293152/6751571 * https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=31881ff3984a8600861f2f4ee32faf23 (Thank you GreenJello)