Skip to content

Commit ff5274f

Browse files
feat: add enum variants
1 parent d8c2e65 commit ff5274f

File tree

4 files changed

+127
-9
lines changed

4 files changed

+127
-9
lines changed

Cargo.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

serde_dhall/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22
name = "serde_dhall"
33
# remember to update html_root_url, README and changelog
4-
version = "0.12.1"
4+
version = "0.12.2"
55
authors = ["Nadrieril <[email protected]>"]
66
license = "BSD-2-Clause"
77
description = "Dhall support for serde"

serde_dhall/src/serialize.rs

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ impl ser::Serializer for Serializer {
6767
type SerializeTupleVariant = ser::Impossible<Self::Ok, Self::Error>;
6868
type SerializeMap = MapSerializer;
6969
type SerializeStruct = StructSerializer;
70-
type SerializeStructVariant = ser::Impossible<Self::Ok, Self::Error>;
70+
type SerializeStructVariant = StructVariantSerializer;
7171

7272
fn serialize_bool(self, v: bool) -> Result<Self::Ok> {
7373
Ok(Num(NumKind::Bool(v)))
@@ -195,13 +195,13 @@ impl ser::Serializer for Serializer {
195195
self,
196196
_name: &'static str,
197197
_variant_index: u32,
198-
_variant: &'static str,
198+
variant: &'static str,
199199
_len: usize,
200200
) -> Result<Self::SerializeStructVariant> {
201-
Err(ErrorKind::Serialize(
202-
"Unsupported data for serialization: struct variant".to_owned(),
203-
)
204-
.into())
201+
Ok(StructVariantSerializer {
202+
variant,
203+
value: BTreeMap::new(),
204+
})
205205
}
206206

207207
fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> {
@@ -339,6 +339,32 @@ impl ser::SerializeStruct for StructSerializer {
339339
}
340340
}
341341

342+
struct StructVariantSerializer {
343+
variant: &'static str,
344+
value: BTreeMap<String, SimpleValue>,
345+
}
346+
347+
impl ser::SerializeStructVariant for StructVariantSerializer {
348+
type Ok = SimpleValue;
349+
type Error = Error;
350+
351+
fn serialize_field<T>(&mut self, key: &'static str, val: &T) -> Result<()>
352+
where
353+
T: ?Sized + ser::Serialize,
354+
{
355+
let val: SimpleValue = val.serialize(Serializer)?;
356+
self.value.insert(key.into(), val);
357+
Ok(())
358+
}
359+
360+
fn end(self) -> Result<Self::Ok> {
361+
Ok(SimpleValue::Union(
362+
self.variant.to_string(),
363+
Some(Box::new(Record(self.value))),
364+
))
365+
}
366+
}
367+
342368
impl serde::ser::Serialize for SimpleValue {
343369
fn serialize<S>(
344370
&self,

serde_dhall/tests/enum_tests.rs

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
mod test_enum {
2+
use serde::{Deserialize, Serialize};
3+
use serde_dhall::{SimpleType, StaticType};
4+
5+
#[derive(
6+
Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize, StaticType,
7+
)]
8+
pub struct ParentStruct {
9+
pub id0: i32,
10+
pub id1: i32,
11+
}
12+
13+
#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, StaticType)]
14+
pub enum EnumVariants {
15+
SimpleStruct {
16+
x: f64,
17+
y: f64,
18+
z: f64,
19+
},
20+
InheritStruct {
21+
field_a: ParentStruct,
22+
field_b: ParentStruct,
23+
},
24+
25+
Unitary,
26+
}
27+
28+
fn build_type() -> SimpleType {
29+
let ty: SimpleType = serde_dhall::from_str(
30+
r#"
31+
let ParentStruct = {id0: Integer, id1: Integer }
32+
33+
let EnumVariant =
34+
< SimpleStruct : { x : Double, y : Double, z : Double }
35+
| InheritStruct: { field_a: ParentStruct, field_b: ParentStruct }
36+
| Unitary
37+
>
38+
in EnumVariant"#,
39+
)
40+
.parse()
41+
.unwrap();
42+
ty
43+
}
44+
45+
#[test]
46+
fn test_enum_simple_struct() {
47+
let v = EnumVariants::SimpleStruct {
48+
x: 1.0,
49+
y: 2.0,
50+
z: 3.0,
51+
};
52+
let v_str = serde_dhall::serialize(&v)
53+
.type_annotation(&build_type())
54+
.to_string()
55+
.unwrap();
56+
println!("{v_str:?}");
57+
let v_deser: EnumVariants =
58+
serde_dhall::from_str(&v_str).parse().unwrap();
59+
assert_eq!(v_deser, v);
60+
}
61+
62+
#[test]
63+
fn test_enum_inherit_struct() {
64+
let v = EnumVariants::InheritStruct {
65+
field_a: ParentStruct { id0: 399, id1: 0 },
66+
field_b: ParentStruct { id0: 301, id1: 0 },
67+
};
68+
69+
let v_str = serde_dhall::serialize(&v)
70+
.type_annotation(&build_type())
71+
.to_string()
72+
.unwrap();
73+
println!("{v_str:?}");
74+
let v_deser: EnumVariants =
75+
serde_dhall::from_str(&v_str).parse().unwrap();
76+
assert_eq!(v_deser, v);
77+
}
78+
79+
#[test]
80+
fn test_enum_unitary() {
81+
let v = EnumVariants::Unitary;
82+
83+
let v_str = serde_dhall::serialize(&v)
84+
.type_annotation(&build_type())
85+
.to_string()
86+
.unwrap();
87+
println!("{v_str:?}");
88+
let v_deser: EnumVariants =
89+
serde_dhall::from_str(&v_str).parse().unwrap();
90+
assert_eq!(v_deser, v);
91+
}
92+
}

0 commit comments

Comments
 (0)