Skip to content
This repository has been archived by the owner on Jan 29, 2023. It is now read-only.

Commit

Permalink
🐛 fix serde deserialization for default fields #11
Browse files Browse the repository at this point in the history
  • Loading branch information
mockersf committed Nov 22, 2019
1 parent 4628768 commit 2ccd179
Showing 1 changed file with 33 additions and 5 deletions.
38 changes: 33 additions & 5 deletions src/serde/de.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ enum Index {

trait Read {
fn get_attribute_value(&self, index: &Index) -> Option<&Hocon>;
fn get_keys(&self) -> Vec<String>;
}
struct HoconRead {
hocon: Hocon,
Expand All @@ -109,6 +110,13 @@ impl Read for HoconRead {
_ => None,
}
}

fn get_keys(&self) -> Vec<String> {
match &self.hocon {
Hocon::Hash(map) => map.keys().cloned().collect(),
_ => unreachable!(),
}
}
}

#[derive(Debug)]
Expand Down Expand Up @@ -329,14 +337,14 @@ impl<'de, 'a, R: Read> serde::de::Deserializer<'de> for &'a mut Deserializer<R>
fn deserialize_struct<V>(
self,
_name: &'static str,
fields: &'static [&'static str],
_fields: &'static [&'static str],
visitor: V,
) -> Result<V::Value>
where
V: serde::de::Visitor<'de>,
{
match self.current_field {
Index::None => visitor.visit_map(MapAccess::new(self, fields)),
Index::None => visitor.visit_map(MapAccess::new(self, self.read.get_keys())),
_ => {
let hc = self
.read
Expand All @@ -345,8 +353,12 @@ impl<'de, 'a, R: Read> serde::de::Deserializer<'de> for &'a mut Deserializer<R>
message: format!("missing struct for field {:?}", &self.current_field),
})?
.clone();
let keys = match &hc {
Hocon::Hash(hm) => hm.keys().cloned().collect(),
_ => unreachable!(),
};
let mut des = Deserializer::new(HoconRead::new(hc));
visitor.visit_map(MapAccess::new(&mut des, fields))
visitor.visit_map(MapAccess::new(&mut des, keys))
}
}
}
Expand Down Expand Up @@ -417,12 +429,12 @@ impl<'de, 'a, R: Read + 'a> serde::de::SeqAccess<'de> for SeqAccess<'a, R> {

struct MapAccess<'a, R: 'a> {
de: &'a mut Deserializer<R>,
keys: &'static [&'static str],
keys: Vec<String>,
current: usize,
}

impl<'a, R: 'a> MapAccess<'a, R> {
fn new(de: &'a mut Deserializer<R>, keys: &'static [&'static str]) -> Self {
fn new(de: &'a mut Deserializer<R>, keys: Vec<String>) -> Self {
MapAccess {
de,
keys,
Expand Down Expand Up @@ -598,4 +610,20 @@ mod tests {
assert!(res.is_ok());
assert_eq!(res.expect("during test").a, vec![5, 7]);
}

#[test]
fn hocon_and_serde_default() {
#[derive(Deserialize, Debug)]
struct MyStructWithDefaultField {
#[serde(default)]
size: f64,
}

// let s: MyStruct = HoconLoader::new().load_str("").unwrap().resolve().unwrap();
let doc = Hocon::Hash(HashMap::new());

let res: super::Result<MyStructWithDefaultField> = dbg!(super::from_hocon(dbg!(doc)));
assert!(res.is_ok());
assert_eq!(res.expect("during test").size, 0.);
}
}

0 comments on commit 2ccd179

Please sign in to comment.