#![cfg(feature = "derive")]
#![allow(clippy::float_cmp)]
use core::mem::offset_of;
use assert2::assert;
use flense::prelude::*;
use super::{
Color,
Other,
Position,
};
#[derive(Adapter)]
struct Reuse {
#[field(Position)]
pos: [f32; 3],
#[field(Color)]
col: [f32; 3],
}
#[test]
fn derive_existing_markers_offsets_match() {
assert!(<Reuse as Adapter<Position>>::OFFSET == offset_of!(Reuse, pos));
assert!(<Reuse as Adapter<Color>>::OFFSET == offset_of!(Reuse, col));
}
#[test]
fn derive_existing_markers_lens_roundtrip() {
let mut r = Reuse {
pos: [1.0, 2.0, 3.0],
col: [4.0, 5.0, 6.0],
};
{
let mut lens: LensMut<'_, (Position, Color)> = r.lens_mut();
*lens.as_mut::<Position, _>() = [10.0, 20.0, 30.0];
assert!(*lens.as_ref::<Color, _>() == [4.0, 5.0, 6.0]);
}
assert!(r.pos == [10.0, 20.0, 30.0]);
assert!(r.col == [4.0, 5.0, 6.0]);
}
#[derive(Adapter)]
struct Stats {
#[field(new Hp)]
hp: u32,
#[field(new Mana)]
mana: u16,
}
#[test]
fn derive_new_markers() {
let _: <Hp as Field>::Type = 0u32;
let _: <Mana as Field>::Type = 0u16;
let mut s = Stats { hp: 100, mana: 50 };
{
let mut lens: LensMut<'_, (Hp, Mana)> = s.lens_mut();
*lens.as_mut::<Hp, _>() = 999;
*lens.as_mut::<Mana, _>() = 7;
}
assert!(s.hp == 999);
assert!(s.mana == 7);
assert!(<Stats as Adapter<Hp>>::OFFSET == offset_of!(Stats, hp));
assert!(<Stats as Adapter<Mana>>::OFFSET == offset_of!(Stats, mana));
}
#[derive(Adapter)]
struct Multi {
#[field(new First, new Second)]
a: u64,
#[field(new Third)]
#[field(Other)]
b: u64,
}
#[test]
fn derive_multiple_entries() {
assert!(<Multi as Adapter<First>>::OFFSET == offset_of!(Multi, a));
assert!(<Multi as Adapter<Second>>::OFFSET == offset_of!(Multi, a));
assert!(<Multi as Adapter<Third>>::OFFSET == offset_of!(Multi, b));
assert!(<Multi as Adapter<Other>>::OFFSET == offset_of!(Multi, b));
let mut m = Multi { a: 1, b: 2 };
{
let mut lens: LensMut<'_, (First, Other)> = m.lens_mut();
*lens.as_mut::<First, _>() = 11;
*lens.as_mut::<Other, _>() = 22;
}
assert!(m.a == 11);
assert!(m.b == 22);
}
#[derive(Adapter)]
struct Wrapper<T> {
payload: T,
#[field(new Tag)]
tag: u32,
}
#[test]
fn derive_generic_struct() {
assert!(<Wrapper<String> as Adapter<Tag>>::OFFSET == offset_of!(Wrapper<String>, tag));
assert!(<Wrapper<[u64; 32]> as Adapter<Tag>>::OFFSET == offset_of!(Wrapper<[u64; 32]>, tag));
assert!(<Wrapper<[u8; 3]> as Adapter<Tag>>::OFFSET == offset_of!(Wrapper<[u8; 3]>, tag));
let mut w = Wrapper::<[u8; 3]> {
payload: [1, 2, 3],
tag: 5,
};
{
let mut lens: LensMut<'_, (Tag,)> = w.lens_mut();
*lens.as_mut::<Tag, _>() = 42;
}
assert!(w.tag == 42);
assert!(w.payload == [1, 2, 3]);
}
#[derive(Adapter)]
struct Reflexive {
#[field(new reflexive Spin)]
spin: [f32; 3],
}
#[test]
fn derive_reflexive_marker() {
assert!(<Reflexive as Adapter<Spin>>::OFFSET == offset_of!(Reflexive, spin));
assert!(<<Spin as Field>::Type as Adapter<Spin>>::OFFSET == 0);
let mut bare = [1.0f32, 2.0, 3.0];
{
let mut lens: LensMut<'_, (Spin,)> = bare.lens_mut();
*lens.as_mut::<Spin, _>() = [4.0, 5.0, 6.0];
}
assert!(bare == [4.0, 5.0, 6.0]);
}
#[derive(Adapter)]
struct Sparse {
_ignored: [u8; 7],
#[field(new Lensed)]
lensed: u64,
}
#[test]
fn derive_ignores_unannotated_fields() {
let mut s = Sparse {
_ignored: [0; 7],
lensed: 0,
};
{
let mut lens: LensMut<'_, (Lensed,)> = s.lens_mut();
*lens.as_mut::<Lensed, _>() = 0xABCD;
}
assert!(s.lensed == 0xABCD);
}