Merge pull request #9 from clouds56/patch-2

split deserialize_seq
This commit is contained in:
zrkn 2020-01-31 03:17:05 +03:00 committed by GitHub
commit a156522b85
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 74 additions and 14 deletions

View File

@ -23,17 +23,7 @@ impl<'lua, 'de> serde::Deserializer<'de> for Deserializer<'lua> {
Value::Integer(v) => visitor.visit_i64(v), Value::Integer(v) => visitor.visit_i64(v),
Value::Number(v) => visitor.visit_f64(v), Value::Number(v) => visitor.visit_f64(v),
Value::String(v) => visitor.visit_str(v.to_str()?), Value::String(v) => visitor.visit_str(v.to_str()?),
Value::Table(v) => if v.contains_key(1)? { Value::Table(v) => {
let len = v.len()? as usize;
let mut deserializer = SeqDeserializer(v.sequence_values());
let seq = visitor.visit_seq(&mut deserializer)?;
let remaining = deserializer.0.count();
if remaining == 0 {
Ok(seq)
} else {
Err(serde::de::Error::invalid_length(len, &"fewer elements in array"))
}
} else {
let len = v.len()? as usize; let len = v.len()? as usize;
let mut deserializer = MapDeserializer(v.pairs(), None); let mut deserializer = MapDeserializer(v.pairs(), None);
let map = visitor.visit_map(&mut deserializer)?; let map = visitor.visit_map(&mut deserializer)?;
@ -90,10 +80,44 @@ impl<'lua, 'de> serde::Deserializer<'de> for Deserializer<'lua> {
visitor.visit_enum(EnumDeserializer { variant, value }) visitor.visit_enum(EnumDeserializer { variant, value })
} }
#[inline]
fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value>
where V: serde::de::Visitor<'de>
{
match self.value {
Value::Table(v) => {
let len = v.len()? as usize;
let mut deserializer = SeqDeserializer(v.sequence_values());
let seq = visitor.visit_seq(&mut deserializer)?;
let remaining = deserializer.0.count();
if remaining == 0 {
Ok(seq)
} else {
Err(serde::de::Error::invalid_length(len, &"fewer elements in array"))
}
}
_ => Err(serde::de::Error::custom("invalid value type")),
}
}
#[inline]
fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value>
where V: serde::de::Visitor<'de>
{
self.deserialize_seq(visitor)
}
#[inline]
fn deserialize_tuple_struct<V>(self, _name: &'static str, _len: usize, visitor: V) -> Result<V::Value>
where V: serde::de::Visitor<'de>
{
self.deserialize_seq(visitor)
}
forward_to_deserialize_any! { forward_to_deserialize_any! {
bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes
byte_buf unit unit_struct newtype_struct seq tuple byte_buf unit unit_struct newtype_struct
tuple_struct map struct identifier ignored_any map struct identifier ignored_any
} }
} }
@ -253,16 +277,26 @@ mod tests {
struct Test { struct Test {
int: u32, int: u32,
seq: Vec<String>, seq: Vec<String>,
map: std::collections::HashMap<i32, i32>,
empty: Vec<()>,
} }
let expected = Test { int: 1, seq: vec!["a".to_owned(), "b".to_owned()] }; let expected = Test {
int: 1,
seq: vec!["a".to_owned(), "b".to_owned()],
map: vec![(1, 2), (4, 1)].into_iter().collect(),
empty: vec![]
};
println!("{:?}", expected);
let lua = Lua::new(); let lua = Lua::new();
lua.context(|lua| { lua.context(|lua| {
let value = lua.load(r#" let value = lua.load(r#"
a = {} a = {}
a.int = 1 a.int = 1
a.seq = {"a", "b"} a.seq = {"a", "b"}
a.map = {2, [4]=1}
a.empty = {}
return a return a
"#).eval().unwrap(); "#).eval().unwrap();
let got = from_value(value).unwrap(); let got = from_value(value).unwrap();
@ -270,6 +304,32 @@ mod tests {
}); });
} }
#[test]
fn test_tuple() {
#[derive(Deserialize, PartialEq, Debug)]
struct Rgb(u8, u8, u8);
let lua = Lua::new();
lua.context(|lua| {
let expected = Rgb(1, 2, 3);
let value = lua.load(
r#"
a = {1, 2, 3}
return a
"#).eval().unwrap();
let got = from_value(value).unwrap();
assert_eq!(expected, got);
let expected = (1, 2, 3);
let value = lua.load(
r#"
a = {1, 2, 3}
return a
"#).eval().unwrap();
let got = from_value(value).unwrap();
assert_eq!(expected, got);
});
}
#[test] #[test]
fn test_enum() { fn test_enum() {