use facet::{Facet, Variance};
use facet_reflect::{Poke, ReflectErrorKind};
#[derive(Debug, Facet)]
struct Borrowed<'a> {
data: &'a str,
}
#[derive(Debug, Facet)]
struct WithMutPtr {
ptr: *mut i32,
}
#[test]
fn poke_pod_struct() {
#[derive(Debug, Facet, PartialEq)]
#[facet(pod)]
struct Point {
x: i32,
y: i32,
}
let mut point = Point { x: 1, y: 2 };
let poke = Poke::new(&mut point);
assert_eq!(poke.shape(), Point::SHAPE);
}
#[test]
fn poke_non_pod_struct_can_be_created() {
#[derive(Debug, Facet)]
struct NotPod {
x: i32,
}
let mut value = NotPod { x: 42 };
let poke = Poke::new(&mut value);
assert_eq!(poke.shape(), NotPod::SHAPE);
}
#[test]
fn poke_non_pod_struct_set_field_fails() {
#[derive(Debug, Facet)]
struct NotPod {
x: i32,
}
let mut value = NotPod { x: 42 };
let poke = Poke::new(&mut value);
let mut poke_struct = poke.into_struct().unwrap();
let result = poke_struct.set_field_by_name("x", 100i32);
assert!(matches!(result, Err(ref err) if matches!(err.kind, ReflectErrorKind::NotPod { .. })));
}
#[test]
fn poke_non_pod_struct_wholesale_replace_works() {
#[derive(Debug, Facet, PartialEq)]
struct NotPod {
x: i32,
}
let mut value = NotPod { x: 42 };
let mut poke = Poke::new(&mut value);
poke.set(NotPod { x: 100 }).unwrap();
assert_eq!(value.x, 100);
}
#[test]
fn poke_primitive() {
let mut x: i32 = 42;
let mut poke = Poke::new(&mut x);
assert_eq!(*poke.get::<i32>().unwrap(), 42);
poke.set(100i32).unwrap();
assert_eq!(x, 100);
}
#[test]
fn poke_get_mut() {
let mut x: i32 = 42;
let mut poke = Poke::new(&mut x);
*poke.get_mut::<i32>().unwrap() = 99;
assert_eq!(x, 99);
}
#[test]
fn poke_wrong_type_fails() {
let mut x: i32 = 42;
let poke = Poke::new(&mut x);
let result = poke.get::<u32>();
assert!(
matches!(result, Err(ref err) if matches!(err.kind, ReflectErrorKind::WrongShape { .. }))
);
}
#[test]
fn poke_set_wrong_type_fails() {
let mut x: i32 = 42;
let mut poke = Poke::new(&mut x);
let result = poke.set(42u32);
assert!(
matches!(result, Err(ref err) if matches!(err.kind, ReflectErrorKind::WrongShape { .. }))
);
}
#[test]
fn poke_string_wholesale_replace() {
let mut s = String::from("hello");
let mut poke = Poke::new(&mut s);
poke.set(String::from("world")).unwrap();
assert_eq!(s, "world");
}
#[test]
fn poke_as_peek() {
#[derive(Debug, Facet, PartialEq)]
#[facet(pod)]
struct Point {
x: i32,
y: i32,
}
let mut point = Point { x: 10, y: 20 };
let poke = Poke::new(&mut point);
let peek = poke.as_peek();
assert_eq!(peek.shape(), Point::SHAPE);
}
#[test]
fn poke_variance_query() {
let mut borrowed = Borrowed { data: "hello" };
let poke = Poke::new(&mut borrowed);
assert_eq!(poke.variance(), Variance::Covariant);
let mut with_ptr = WithMutPtr {
ptr: std::ptr::null_mut(),
};
let poke = Poke::new(&mut with_ptr);
assert_eq!(poke.variance(), Variance::Invariant);
}
#[test]
fn poke_try_reborrow_covariant() {
static DATA: &str = "hello";
let mut borrowed: Borrowed<'static> = Borrowed { data: DATA };
let mut poke: Poke<'_, 'static> = Poke::new(&mut borrowed);
let mut reborrowed = poke.try_reborrow().expect("Borrowed is covariant");
reborrowed.set(Borrowed { data: "world" }).unwrap();
assert_eq!(borrowed.data, "world");
}
#[test]
fn poke_try_reborrow_invariant_returns_none() {
let mut with_ptr = WithMutPtr {
ptr: std::ptr::null_mut(),
};
let mut poke: Poke<'_, 'static> = Poke::new(&mut with_ptr);
let result: Option<Poke<'_, '_>> = poke.try_reborrow();
assert!(result.is_none());
}