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

Commit

Permalink
Add support for enum as keys in maps
Browse files Browse the repository at this point in the history
  • Loading branch information
mredaelli committed Apr 24, 2020
1 parent dfab16c commit f2339b1
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 24 deletions.
2 changes: 1 addition & 1 deletion src/helper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ where
.err()
.expect("should be err as it was fitlered before")
})
.nth(0)
.next()
{
return Err(err);
}
Expand Down
2 changes: 1 addition & 1 deletion src/internals/intermediate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ impl Node {
(Node::Leaf(_), ref path) if path.is_empty() => Ok(self.clone()),
(Node::Node { children, .. }, _) => {
let mut iter = path.clone().into_iter();
let first = iter.nth(0);
let first = iter.next();
let remaining = iter.collect();

match first {
Expand Down
87 changes: 68 additions & 19 deletions src/serde/de.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use serde;

use super::error::{Error, Result};
use crate::Hocon;

Expand All @@ -12,12 +10,14 @@ macro_rules! impl_deserialize_n {
visitor.$visit(
self.read
.get_attribute_value(&self.current_field)
.ok_or_else(|| Error { message: format!("missing integer for field \"{}\"",
self.current_field) })?
.ok_or_else(|| Error {
message: format!("missing integer for field \"{}\"", self.current_field),
})?
.clone()
.as_i64()
.ok_or_else(|| Error { message: format!("missing integer for field \"{}\"",
self.current_field) })?
.ok_or_else(|| Error {
message: format!("missing integer for field \"{}\"", self.current_field),
})?,
)
}
};
Expand All @@ -29,12 +29,14 @@ macro_rules! impl_deserialize_n {
visitor.$visit(
self.read
.get_attribute_value(&self.current_field)
.ok_or_else(|| Error { message: format!("missing integer for field \"{}\"",
self.current_field) })?
.ok_or_else(|| Error {
message: format!("missing integer for field \"{}\"", self.current_field),
})?
.clone()
.as_i64()
.ok_or_else(|| Error { message: format!("missing integer for field \"{}\"",
self.current_field) })? as $type
.ok_or_else(|| Error {
message: format!("missing integer for field \"{}\"", self.current_field),
})? as $type,
)
}
};
Expand All @@ -48,15 +50,16 @@ macro_rules! impl_deserialize_f {
visitor.$visit(
self.read
.get_attribute_value(&self.current_field)
.ok_or_else(|| Error { message: format!("missing float for field \"{}\"",
self.current_field) })?
.ok_or_else(|| Error {
message: format!("missing float for field \"{}\"", self.current_field),
})?
.clone()
.as_f64()
.ok_or_else(|| Error { message: format!("missing float for field \"{}\"",
self.current_field) })?
.ok_or_else(|| Error {
message: format!("missing float for field \"{}\"", self.current_field),
})?,
)
}

};
($type:ty, $method:ident, $visit:ident) => {
fn $method<V>(self, visitor: V) -> Result<V::Value>
Expand All @@ -66,12 +69,14 @@ macro_rules! impl_deserialize_f {
visitor.$visit(
self.read
.get_attribute_value(&self.current_field)
.ok_or_else(|| Error { message: format!("missing float for field \"{}\"",
self.current_field) })?
.ok_or_else(|| Error {
message: format!("missing float for field \"{}\"", self.current_field),
})?
.clone()
.as_f64()
.ok_or_else(|| Error { message: format!("missing float for field \"{}\"",
self.current_field) })? as $type
.ok_or_else(|| Error {
message: format!("missing float for field \"{}\"", self.current_field),
})? as $type,
)
}
};
Expand Down Expand Up @@ -446,6 +451,17 @@ impl<'de, 'a, R: Read> serde::de::Deserializer<'de> for &'a mut Deserializer<R>
})?
.clone();

if let Index::String(ref s) = self.current_field {
for v in _variants {
if s == v {
let reader = HoconRead::new(hc);
let deserializer = &mut Deserializer::new(reader);
deserializer.current_field = Index::String(String::from(s));
return visitor.visit_enum(UnitVariantAccess::new(deserializer));
}
}
}

match &hc {
Hocon::String(name) => {
let index = Index::String(String::from(name));
Expand Down Expand Up @@ -928,6 +944,39 @@ mod tests {
assert_eq!(res.expect("during test").item.get("Hello"), Some(&7));
}

#[test]
fn map_with_enum_keys() {
#[derive(Deserialize, Debug, Hash, PartialEq, Eq)]
enum E {
A,
B,
}

let mut hm = HashMap::new();
hm.insert(String::from("A"), Hocon::Integer(1));
hm.insert(String::from("B"), Hocon::Integer(2));
let doc = Hocon::Hash(hm);

let res: super::Result<HashMap<E, u8>> = dbg!(super::from_hocon(dbg!(doc)));
assert!(res.is_ok());
assert_eq!(res.expect("during test").get(&E::A), Some(&1));

#[derive(Deserialize, Debug)]
struct S {
s: u8,
}

let mut hm = HashMap::new();
let mut hm_sub = HashMap::new();
hm_sub.insert(String::from("s"), Hocon::Integer(7));
hm.insert(String::from("A"), Hocon::Hash(hm_sub));
let doc = Hocon::Hash(hm);

let res: super::Result<HashMap<E, S>> = dbg!(super::from_hocon(dbg!(doc)));
assert!(res.is_ok());
assert_eq!(res.expect("during test").get(&E::A).unwrap().s, 7);
}

#[derive(Deserialize, Debug, PartialEq)]
enum MyEnum {
UnitVariant,
Expand Down
3 changes: 0 additions & 3 deletions src/serde/error.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
use serde;
use std;

pub(crate) type Result<T> = std::result::Result<T, Error>;

#[derive(Debug)]
Expand Down

0 comments on commit f2339b1

Please sign in to comment.