mirror of
https://github.com/danbulant/convex-macros
synced 2026-07-05 19:11:08 +00:00
fix: update enum serialization (#2)
This commit is contained in:
parent
73054ea2e5
commit
077d69ea8b
2 changed files with 77 additions and 9 deletions
32
src/model.rs
32
src/model.rs
|
|
@ -109,9 +109,9 @@ impl ConvexField {
|
||||||
let ignore_attributes = quote! {
|
let ignore_attributes = quote! {
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
};
|
};
|
||||||
let struct_attributes = quote! {
|
// Note: We need a custom serialize to avoid unions printing as objects.
|
||||||
|
let enum_struct_attributes = quote! {
|
||||||
#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
|
#[derive(::serde::Deserialize, Clone, Debug)]
|
||||||
};
|
};
|
||||||
|
|
||||||
match &self.t {
|
match &self.t {
|
||||||
|
|
@ -126,6 +126,7 @@ impl ConvexField {
|
||||||
let mut enum_kinds = Vec::new();
|
let mut enum_kinds = Vec::new();
|
||||||
let mut extract_arms = Vec::new();
|
let mut extract_arms = Vec::new();
|
||||||
let mut json_arms: Vec<TokenStream> = Vec::new();
|
let mut json_arms: Vec<TokenStream> = Vec::new();
|
||||||
|
let mut serialize_arms: Vec<TokenStream> = Vec::new();
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
for t in types {
|
for t in types {
|
||||||
i += 1;
|
i += 1;
|
||||||
|
|
@ -146,6 +147,9 @@ impl ConvexField {
|
||||||
json_arms.push(quote! {
|
json_arms.push(quote! {
|
||||||
| #struct_name::#branch_name => ::serde_json::Value::Null,
|
| #struct_name::#branch_name => ::serde_json::Value::Null,
|
||||||
});
|
});
|
||||||
|
serialize_arms.push(quote! {
|
||||||
|
| #struct_name::#branch_name => ().serialize(serializer),
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
enum_kinds.push(quote! {
|
enum_kinds.push(quote! {
|
||||||
#branch_name(#branch_type),
|
#branch_name(#branch_type),
|
||||||
|
|
@ -153,6 +157,9 @@ impl ConvexField {
|
||||||
json_arms.push(quote! {
|
json_arms.push(quote! {
|
||||||
| #struct_name::#branch_name(value) => ::serde_json::json!(value),
|
| #struct_name::#branch_name(value) => ::serde_json::json!(value),
|
||||||
});
|
});
|
||||||
|
serialize_arms.push(quote! {
|
||||||
|
| #struct_name::#branch_name(ref value) => value.serialize(serializer),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
| None => {
|
| None => {
|
||||||
|
|
@ -162,6 +169,9 @@ impl ConvexField {
|
||||||
json_arms.push(quote! {
|
json_arms.push(quote! {
|
||||||
| #struct_name::#branch_name(value) => ::serde_json::json!(value),
|
| #struct_name::#branch_name(value) => ::serde_json::json!(value),
|
||||||
});
|
});
|
||||||
|
serialize_arms.push(quote! {
|
||||||
|
| #struct_name::#branch_name(ref value) => value.serialize(serializer),
|
||||||
|
});
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
match t {
|
match t {
|
||||||
|
|
@ -241,12 +251,24 @@ impl ConvexField {
|
||||||
|
|
||||||
structs.push(quote! {
|
structs.push(quote! {
|
||||||
#ignore_attributes
|
#ignore_attributes
|
||||||
#struct_attributes
|
#enum_struct_attributes
|
||||||
pub enum #struct_name {
|
pub enum #struct_name {
|
||||||
#( #enum_kinds )*
|
#( #enum_kinds )*
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
impls.push(quote! {
|
||||||
|
#ignore_attributes
|
||||||
|
impl ::serde::Serialize for #struct_name {
|
||||||
|
fn serialize<S>(&self, serializer: S) -> ::core::result::Result<S::Ok, S::Error>
|
||||||
|
where S: ::serde::Serializer {
|
||||||
|
match *self {
|
||||||
|
#( #serialize_arms )*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
impls.push(quote! {
|
impls.push(quote! {
|
||||||
#ignore_attributes
|
#ignore_attributes
|
||||||
impl #struct_name {
|
impl #struct_name {
|
||||||
|
|
@ -312,7 +334,7 @@ impl ConvexField {
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
};
|
};
|
||||||
let struct_attributes = quote! {
|
let struct_attributes = quote! {
|
||||||
#[derive(serde::Deserialize, serde::Serialize, Clone, Debug)]
|
#[derive(::serde::Serialize, ::serde::Deserialize, Clone, Debug)]
|
||||||
};
|
};
|
||||||
let mut structs = Vec::new();
|
let mut structs = Vec::new();
|
||||||
let mut rendered_fields = Vec::new();
|
let mut rendered_fields = Vec::new();
|
||||||
|
|
|
||||||
|
|
@ -59,10 +59,56 @@ fn example() {
|
||||||
"seven": "seven",
|
"seven": "seven",
|
||||||
"eight": false,
|
"eight": false,
|
||||||
"nine": 9,
|
"nine": 9,
|
||||||
// TODO: Fix this.
|
"ten": 10.0,
|
||||||
"ten": {
|
});
|
||||||
"Variant2": 10.0
|
|
||||||
},
|
let actual_json_data = json!(model);
|
||||||
|
assert_eq!(expected_json_data, actual_json_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
convex_model!(BasicUnion { value: v.union(v.string(), v.number()) });
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn example2() {
|
||||||
|
let convex_data = Value::Object(btreemap! {
|
||||||
|
"value".into() => Value::String("hi".into()),
|
||||||
|
});
|
||||||
|
|
||||||
|
let model = BasicUnion::from_convex_value(&convex_data)
|
||||||
|
.expect("Model should parse data");
|
||||||
|
|
||||||
|
if let BasicUnionValue::Variant1(value) = &model.value {
|
||||||
|
assert_eq!("hi", value);
|
||||||
|
} else {
|
||||||
|
panic!("Expected 10.0")
|
||||||
|
}
|
||||||
|
|
||||||
|
let expected_json_data = json!({
|
||||||
|
"value": "hi",
|
||||||
|
});
|
||||||
|
|
||||||
|
let actual_json_data = json!(model);
|
||||||
|
assert_eq!(expected_json_data, actual_json_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
convex_model!(NullUnion { value: v.union(v.string(), v.null()) });
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn example3() {
|
||||||
|
let convex_data = Value::Object(btreemap! {
|
||||||
|
"value".into() => Value::Null,
|
||||||
|
});
|
||||||
|
|
||||||
|
let model = NullUnion::from_convex_value(&convex_data)
|
||||||
|
.expect("Model should parse data");
|
||||||
|
|
||||||
|
if let NullUnionValue::Variant2 = &model.value {
|
||||||
|
} else {
|
||||||
|
panic!("Expected Unit")
|
||||||
|
}
|
||||||
|
|
||||||
|
let expected_json_data = json!({
|
||||||
|
"value": null,
|
||||||
});
|
});
|
||||||
|
|
||||||
let actual_json_data = json!(model);
|
let actual_json_data = json!(model);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue