use facet::Facet;
use facet_testhelpers::test;
#[derive(Facet, Clone, PartialEq, Debug)]
pub struct Inner {
pub value: f64,
}
#[derive(Facet, Clone, PartialEq, Debug)]
#[facet(tag = "type")]
#[repr(C)]
pub enum Tagged {
TypeA(Inner),
TypeB(Inner),
}
#[derive(Facet, Clone, PartialEq, Debug)]
pub struct Outer {
#[facet(flatten)]
pub tagged: Tagged,
}
#[test]
fn test_single_flattened_tagged_enum_deserialize() {
let json_single = r#"{"type":"TypeA","value":42.0}"#;
let single: Outer = facet_json::from_str(json_single).expect("single should work");
assert!(matches!(single.tagged, Tagged::TypeA(_)));
if let Tagged::TypeA(inner) = &single.tagged {
assert_eq!(inner.value, 42.0);
}
}
#[test]
fn test_vec_flattened_tagged_enum_deserialize() {
let json_vec = r#"[{"type":"TypeA","value":42.0},{"type":"TypeB","value":99.0}]"#;
let vec_result: Result<Vec<Outer>, _> = facet_json::from_str(json_vec);
assert!(
vec_result.is_ok(),
"Vec deserialization should work but fails with: {:?}",
vec_result.err()
);
let vec = vec_result.unwrap();
assert_eq!(vec.len(), 2);
assert!(matches!(vec[0].tagged, Tagged::TypeA(_)));
if let Tagged::TypeA(inner) = &vec[0].tagged {
assert_eq!(inner.value, 42.0);
}
assert!(matches!(vec[1].tagged, Tagged::TypeB(_)));
if let Tagged::TypeB(inner) = &vec[1].tagged {
assert_eq!(inner.value, 99.0);
}
}
#[test]
fn test_two_elements_same_variant() {
let json = r#"[{"type":"TypeA","value":1.0},{"type":"TypeA","value":2.0}]"#;
let result: Result<Vec<Outer>, _> = facet_json::from_str(json);
assert!(
result.is_ok(),
"Two elements with same variant should work but fails with: {:?}",
result.err()
);
}
#[test]
fn test_single_element_in_vec() {
let json = r#"[{"type":"TypeA","value":1.0}]"#;
let result: Result<Vec<Outer>, _> = facet_json::from_str(json);
assert!(
result.is_ok(),
"Single element in Vec should work but fails with: {:?}",
result.err()
);
}
#[derive(Facet, Clone, PartialEq, Debug)]
#[facet(tag = "type")]
#[repr(C)]
pub enum TaggedScalar {
TypeA(f64),
TypeB(f64),
}
#[derive(Facet, Clone, PartialEq, Debug)]
pub struct OuterScalar {
#[facet(flatten)]
pub tagged: TaggedScalar,
}
#[test]
fn test_scalar_tuple_variant_in_vec() {
}
#[derive(Facet, Clone, PartialEq, Debug)]
#[facet(tag = "type")]
#[repr(C)]
pub enum TaggedStruct {
TypeA { value: f64 },
TypeB { value: f64 },
}
#[derive(Facet, Clone, PartialEq, Debug)]
pub struct OuterStruct {
#[facet(flatten)]
pub tagged: TaggedStruct,
}
#[test]
fn test_struct_variant_in_vec() {
let json = r#"[{"type":"TypeA","value":1.0}]"#;
let result: Result<Vec<OuterStruct>, _> = facet_json::from_str(json);
assert!(
result.is_ok(),
"Struct variant in Vec should work but fails with: {:?}",
result.err()
);
}
#[test]
fn test_roundtrip_vec_flattened_tagged_enum() {
let original = vec![
Outer {
tagged: Tagged::TypeA(Inner { value: 42.0 }),
},
Outer {
tagged: Tagged::TypeB(Inner { value: 99.0 }),
},
];
let json = facet_json::to_string(&original).expect("serialization should work");
let deserialized: Vec<Outer> =
facet_json::from_str(&json).expect("deserialization should work");
assert_eq!(original, deserialized);
}