use facet::Facet;
use facet_reflect::Partial;
use facet_testhelpers::{IPanic, test};
#[test]
fn vec_struct_element_deferred_simple() -> Result<(), IPanic> {
#[derive(Facet, Debug, PartialEq)]
struct Item {
a: u32,
b: String,
}
let mut partial = Partial::alloc::<Vec<Item>>()?;
partial = partial.init_list()?;
partial = partial.begin_list_item()?;
partial = partial.begin_deferred()?;
partial = partial.set_field("a", 1u32)?;
partial = partial.set_field("b", String::from("first"))?;
partial = partial.finish_deferred()?;
partial = partial.end()?;
partial = partial.begin_list_item()?;
partial = partial.begin_deferred()?;
partial = partial.set_field("a", 2u32)?;
partial = partial.set_field("b", String::from("second"))?;
partial = partial.finish_deferred()?;
partial = partial.end()?;
let result = partial.build()?.materialize::<Vec<Item>>()?;
assert_eq!(result.len(), 2);
assert_eq!(
result[0],
Item {
a: 1,
b: String::from("first")
}
);
assert_eq!(
result[1],
Item {
a: 2,
b: String::from("second")
}
);
Ok(())
}
#[test]
fn vec_struct_element_deferred_interleaved_fields() -> Result<(), IPanic> {
#[derive(Facet, Debug, PartialEq)]
struct Item {
x: u32,
y: u32,
z: u32,
}
let mut partial = Partial::alloc::<Vec<Item>>()?;
partial = partial.init_list()?;
partial = partial.begin_list_item()?;
partial = partial.begin_deferred()?;
partial = partial.set_field("x", 1u32)?;
partial = partial.set_field("z", 3u32)?;
partial = partial.set_field("y", 2u32)?;
partial = partial.finish_deferred()?;
partial = partial.end()?;
let result = partial.build()?.materialize::<Vec<Item>>()?;
assert_eq!(result.len(), 1);
assert_eq!(result[0], Item { x: 1, y: 2, z: 3 });
Ok(())
}
#[test]
fn vec_nested_struct_element_deferred() -> Result<(), IPanic> {
#[derive(Facet, Debug, PartialEq)]
struct Inner {
value: i32,
}
#[derive(Facet, Debug, PartialEq)]
struct Outer {
name: String,
inner: Inner,
}
let mut partial = Partial::alloc::<Vec<Outer>>()?;
partial = partial.init_list()?;
partial = partial.begin_list_item()?;
partial = partial.begin_deferred()?;
partial = partial.set_field("name", String::from("test"))?;
partial = partial.begin_field("inner")?;
partial = partial.set_field("value", 42i32)?;
partial = partial.end()?;
partial = partial.finish_deferred()?;
partial = partial.end()?;
let result = partial.build()?.materialize::<Vec<Outer>>()?;
assert_eq!(result.len(), 1);
assert_eq!(result[0].name, "test");
assert_eq!(result[0].inner.value, 42);
Ok(())
}
#[test]
fn vec_nested_struct_interleaved_reentry() -> Result<(), IPanic> {
#[derive(Facet, Debug, PartialEq)]
struct Inner {
a: u32,
b: u32,
}
#[derive(Facet, Debug, PartialEq)]
struct Outer {
inner: Inner,
name: String,
}
let mut partial = Partial::alloc::<Vec<Outer>>()?;
partial = partial.init_list()?;
partial = partial.begin_list_item()?;
partial = partial.begin_deferred()?;
partial = partial.begin_field("inner")?;
partial = partial.set_field("a", 1u32)?;
partial = partial.end()?;
partial = partial.set_field("name", String::from("test"))?;
partial = partial.begin_field("inner")?;
partial = partial.set_field("b", 2u32)?;
partial = partial.end()?;
partial = partial.finish_deferred()?;
partial = partial.end()?;
let result = partial.build()?.materialize::<Vec<Outer>>()?;
assert_eq!(result.len(), 1);
assert_eq!(result[0].inner.a, 1);
assert_eq!(result[0].inner.b, 2);
assert_eq!(result[0].name, "test");
Ok(())
}
#[test]
fn vec_enum_element_simple() -> Result<(), IPanic> {
#[derive(Facet, Debug, PartialEq)]
#[repr(u8)]
enum Item {
A { value: u32 },
B { x: u32, y: u32 },
}
let mut partial = Partial::alloc::<Vec<Item>>()?;
partial = partial.init_list()?;
partial = partial.begin_list_item()?;
partial = partial.begin_deferred()?;
partial = partial.select_variant_named("A")?;
partial = partial.set_field("value", 42u32)?;
partial = partial.finish_deferred()?;
partial = partial.end()?;
partial = partial.begin_list_item()?;
partial = partial.begin_deferred()?;
partial = partial.select_variant_named("B")?;
partial = partial.set_field("x", 1u32)?;
partial = partial.set_field("y", 2u32)?;
partial = partial.finish_deferred()?;
partial = partial.end()?;
let result = partial.build()?.materialize::<Vec<Item>>()?;
assert_eq!(result.len(), 2);
assert_eq!(result[0], Item::A { value: 42 });
assert_eq!(result[1], Item::B { x: 1, y: 2 });
Ok(())
}
#[test]
fn vec_enum_element_interleaved_variant_fields() -> Result<(), IPanic> {
#[derive(Facet, Debug, PartialEq)]
#[repr(u8)]
enum Item {
Record { id: u32, name: String, score: i32 },
}
#[derive(Facet, Debug, PartialEq)]
struct Wrapper {
item: Item,
tag: String,
}
let mut partial = Partial::alloc::<Vec<Wrapper>>()?;
partial = partial.init_list()?;
partial = partial.begin_list_item()?;
partial = partial.begin_deferred()?;
partial = partial.begin_field("item")?;
partial = partial.select_variant_named("Record")?;
partial = partial.set_field("id", 1u32)?;
partial = partial.end()?;
partial = partial.set_field("tag", String::from("important"))?;
partial = partial.begin_field("item")?;
partial = partial.set_field("name", String::from("test"))?;
partial = partial.set_field("score", 100i32)?;
partial = partial.end()?;
partial = partial.finish_deferred()?;
partial = partial.end()?;
let result = partial.build()?.materialize::<Vec<Wrapper>>()?;
assert_eq!(result.len(), 1);
assert_eq!(result[0].tag, "important");
assert_eq!(
result[0].item,
Item::Record {
id: 1,
name: String::from("test"),
score: 100
}
);
Ok(())
}
#[test]
fn vec_many_elements_with_deferred() -> Result<(), IPanic> {
#[derive(Facet, Debug, PartialEq)]
struct Item {
id: u32,
data: String,
}
let mut partial = Partial::alloc::<Vec<Item>>()?;
partial = partial.init_list()?;
for i in 0..20 {
partial = partial.begin_list_item()?;
partial = partial.begin_deferred()?;
partial = partial.set_field("id", i as u32)?;
partial = partial.set_field("data", format!("item_{}", i))?;
partial = partial.finish_deferred()?;
partial = partial.end()?;
}
let result = partial.build()?.materialize::<Vec<Item>>()?;
assert_eq!(result.len(), 20);
(0..20).for_each(|i| {
assert_eq!(result[i].id, i as u32);
assert_eq!(result[i].data, format!("item_{}", i));
});
Ok(())
}
#[test]
fn vec_many_elements_interleaved_fields() -> Result<(), IPanic> {
#[derive(Facet, Debug, PartialEq)]
struct Item {
a: u32,
b: u32,
c: u32,
}
let mut partial = Partial::alloc::<Vec<Item>>()?;
partial = partial.init_list()?;
for i in 0..15 {
partial = partial.begin_list_item()?;
partial = partial.begin_deferred()?;
partial = partial.set_field("c", (i * 3 + 2) as u32)?;
partial = partial.set_field("a", (i * 3) as u32)?;
partial = partial.set_field("b", (i * 3 + 1) as u32)?;
partial = partial.finish_deferred()?;
partial = partial.end()?;
}
let result = partial.build()?.materialize::<Vec<Item>>()?;
assert_eq!(result.len(), 15);
(0..15).for_each(|i| {
assert_eq!(result[i].a, (i * 3) as u32);
assert_eq!(result[i].b, (i * 3 + 1) as u32);
assert_eq!(result[i].c, (i * 3 + 2) as u32);
});
Ok(())
}
#[test]
fn vec_of_vec_with_deferred() -> Result<(), IPanic> {
#[derive(Facet, Debug, PartialEq)]
struct Row {
items: Vec<u32>,
label: String,
}
let mut partial = Partial::alloc::<Vec<Row>>()?;
partial = partial.init_list()?;
partial = partial.begin_list_item()?;
partial = partial.begin_deferred()?;
partial = partial.begin_field("items")?;
partial = partial.init_list()?;
partial = partial.push(1u32)?;
partial = partial.push(2u32)?;
partial = partial.end()?;
partial = partial.set_field("label", String::from("row1"))?;
partial = partial.finish_deferred()?;
partial = partial.end()?;
partial = partial.begin_list_item()?;
partial = partial.begin_deferred()?;
partial = partial.set_field("label", String::from("row2"))?;
partial = partial.begin_field("items")?;
partial = partial.init_list()?;
partial = partial.push(3u32)?;
partial = partial.push(4u32)?;
partial = partial.push(5u32)?;
partial = partial.end()?;
partial = partial.finish_deferred()?;
partial = partial.end()?;
let result = partial.build()?.materialize::<Vec<Row>>()?;
assert_eq!(result.len(), 2);
assert_eq!(result[0].items, vec![1, 2]);
assert_eq!(result[0].label, "row1");
assert_eq!(result[1].items, vec![3, 4, 5]);
assert_eq!(result[1].label, "row2");
Ok(())
}
#[test]
fn container_with_vec_of_deferred_structs() -> Result<(), IPanic> {
#[derive(Facet, Debug, PartialEq)]
struct Item {
x: u32,
y: u32,
}
#[derive(Facet, Debug, PartialEq)]
struct Container {
name: String,
items: Vec<Item>,
count: u32,
}
let mut partial = Partial::alloc::<Container>()?;
partial = partial.begin_deferred()?;
partial = partial.set_field("name", String::from("container"))?;
partial = partial.begin_field("items")?;
partial = partial.init_list()?;
partial = partial.begin_list_item()?;
partial = partial.set_field("y", 2u32)?; partial = partial.set_field("x", 1u32)?;
partial = partial.end()?;
partial = partial.begin_list_item()?;
partial = partial.set_field("x", 3u32)?;
partial = partial.set_field("y", 4u32)?;
partial = partial.end()?;
partial = partial.end()?;
partial = partial.set_field("count", 2u32)?;
partial = partial.finish_deferred()?;
let result = partial.build()?.materialize::<Container>()?;
assert_eq!(result.name, "container");
assert_eq!(result.count, 2);
assert_eq!(result.items.len(), 2);
assert_eq!(result.items[0], Item { x: 1, y: 2 });
assert_eq!(result.items[1], Item { x: 3, y: 4 });
Ok(())
}
#[test]
fn vec_single_element_deferred() -> Result<(), IPanic> {
#[derive(Facet, Debug, PartialEq)]
struct Item {
value: u32,
}
let mut partial = Partial::alloc::<Vec<Item>>()?;
partial = partial.init_list()?;
partial = partial.begin_list_item()?;
partial = partial.begin_deferred()?;
partial = partial.set_field("value", 42u32)?;
partial = partial.finish_deferred()?;
partial = partial.end()?;
let result = partial.build()?.materialize::<Vec<Item>>()?;
assert_eq!(result.len(), 1);
assert_eq!(result[0].value, 42);
Ok(())
}
#[test]
fn vec_empty_with_init() -> Result<(), IPanic> {
#[derive(Facet, Debug, PartialEq)]
struct Item {
value: u32,
}
let mut partial = Partial::alloc::<Vec<Item>>()?;
partial = partial.init_list()?;
let result = partial.build()?.materialize::<Vec<Item>>()?;
assert!(result.is_empty());
Ok(())
}
#[test]
fn vec_zst_elements() -> Result<(), IPanic> {
#[derive(Facet, Debug, PartialEq)]
struct Empty;
let mut partial = Partial::alloc::<Vec<Empty>>()?;
partial = partial.init_list()?;
for _ in 0..5 {
partial = partial.begin_list_item()?;
partial = partial.set(Empty)?;
partial = partial.end()?;
}
let result = partial.build()?.materialize::<Vec<Empty>>()?;
assert_eq!(result.len(), 5);
Ok(())
}
#[test]
fn issue_2010_reproduction_partial_level() -> Result<(), IPanic> {
#[derive(Facet, Debug, PartialEq)]
#[repr(u8)]
enum Inner {
TypeA { value: f64 },
TypeB { alpha: f64, beta: f64 },
}
#[derive(Facet, Debug, PartialEq)]
struct Item {
inner: Inner,
extra: Option<String>,
}
let mut partial = Partial::alloc::<Vec<Item>>()?;
partial = partial.init_list()?;
partial = partial.begin_list_item()?;
partial = partial.begin_deferred()?;
partial = partial.begin_field("inner")?;
partial = partial.select_variant_named("TypeB")?;
partial = partial.set_field("alpha", 1.0f64)?;
partial = partial.end()?;
partial = partial.begin_field("extra")?;
partial = partial.begin_some()?;
partial = partial.set(String::from("test"))?;
partial = partial.end()?;
partial = partial.end()?;
partial = partial.begin_field("inner")?;
partial = partial.set_field("beta", 2.0f64)?;
partial = partial.end()?;
partial = partial.finish_deferred()?;
partial = partial.end()?;
let result = partial.build()?.materialize::<Vec<Item>>()?;
assert_eq!(result.len(), 1);
assert_eq!(
result[0].inner,
Inner::TypeB {
alpha: 1.0,
beta: 2.0
}
);
assert_eq!(result[0].extra, Some(String::from("test")));
Ok(())
}