flense 0.2.2

Purpose-oriented lensing
Documentation
//! Tests for [`LensSliceMut`].

#![allow(clippy::float_cmp)]

#[path = "./common.rs"]
mod common;

use assert2::assert;
use common::*;
use flense::prelude::*;

#[allow(clippy::cast_possible_truncation, clippy::cast_precision_loss)]
#[test]
fn split_lens_slice_mut() {
    let mut verts = [
        Vertex {
            position: [1.0, 2.0, 3.0],
            color: [4.0, 5.0, 6.0],
            normal: [7, 8],
            other: 0xAA,
        },
        Vertex {
            position: [10.0, 20.0, 30.0],
            color: [40.0, 50.0, 60.0],
            normal: [70, 80],
            other: 0xBB,
        },
    ];
    {
        let lens: LensSliceMut<'_, (Normal, Other, Color, Position)> =
            verts.as_mut_slice().lens_slice_mut();
        let (mut lhs, mut rhs) = lens.split::<(Color, Other), _>();
        assert!(lhs.len() == 2);
        assert!(rhs.len() == 2);

        for i in 0..2 {
            *lhs.get_mut::<Color, _>(i).unwrap() = [100.0 + i as f32, 0.0, 0.0];
            *lhs.get_mut::<Other, _>(i).unwrap() = 0x1000 + i as u64;
            *rhs.get_mut::<Position, _>(i).unwrap() = [200.0 + i as f32, 0.0, 0.0];
            *rhs.get_mut::<Normal, _>(i).unwrap() = [i as u8, (i + 1) as u8];
        }
    }

    assert!(verts[0].color == [100.0, 0.0, 0.0]);
    assert!(verts[1].color == [101.0, 0.0, 0.0]);
    assert!(verts[0].other == 0x1000);
    assert!(verts[1].other == 0x1001);
    assert!(verts[0].position == [200.0, 0.0, 0.0]);
    assert!(verts[1].position == [201.0, 0.0, 0.0]);
    assert!(verts[0].normal == [0, 1]);
    assert!(verts[1].normal == [1, 2]);
}

#[allow(clippy::cast_possible_truncation, clippy::cast_precision_loss)]
#[test]
fn lens_slice_mut_get_mut() {
    let mut verts = [
        Vertex {
            position: [1.0, 2.0, 3.0],
            color: [4.0, 5.0, 6.0],
            normal: [7, 8],
            other: 0xAA,
        },
        Vertex {
            position: [10.0, 20.0, 30.0],
            color: [40.0, 50.0, 60.0],
            normal: [70, 80],
            other: 0xBB,
        },
    ];
    {
        let mut lens: LensSliceMut<'_, (Normal, Other, Color, Position)> =
            verts.as_mut_slice().lens_slice_mut();
        for i in 0..2 {
            *lens.get_mut::<Position, _>(i).unwrap() = [200.0 + i as f32, 0.0, 0.0];
            *lens.get_mut::<Other, _>(i).unwrap() = 0x1000 + i as u64;
            *lens.get_mut::<Color, _>(i).unwrap() = [100.0 + i as f32, 0.0, 0.0];
            *lens.get_mut::<Normal, _>(i).unwrap() = [i as u8, (i + 1) as u8];
            // Shared accessors observe the just-written values.
            assert!(*lens.get::<Position, _>(i).unwrap() == [200.0 + i as f32, 0.0, 0.0]);
            assert!(*lens.get::<Color, _>(i).unwrap() == [100.0 + i as f32, 0.0, 0.0]);
        }
        assert!(lens.get_mut::<Position, _>(2).is_none());
        assert!(lens.get::<Position, _>(2).is_none());
    }
    assert!(verts[0].position == [200.0, 0.0, 0.0]);
    assert!(verts[1].position == [201.0, 0.0, 0.0]);
    assert!(verts[0].color == [100.0, 0.0, 0.0]);
    assert!(verts[1].color == [101.0, 0.0, 0.0]);
    assert!(verts[0].other == 0x1000);
    assert!(verts[1].other == 0x1001);
    assert!(verts[0].normal == [0, 1]);
    assert!(verts[1].normal == [1, 2]);
}

#[allow(clippy::cast_possible_truncation, clippy::cast_precision_loss)]
#[test]
fn lens_slice_mut_get_all() {
    let mut verts = [
        Vertex {
            position: [1.0, 2.0, 3.0],
            color: [4.0, 5.0, 6.0],
            normal: [7, 8],
            other: 0xAA,
        },
        Vertex {
            position: [10.0, 20.0, 30.0],
            color: [40.0, 50.0, 60.0],
            normal: [70, 80],
            other: 0xBB,
        },
    ];
    let expected = verts;
    let lens: LensSliceMut<'_, (Normal, Other, Color, Position)> =
        verts.as_mut_slice().lens_slice_mut();

    for (i, v) in expected.iter().enumerate() {
        let l = lens.get_all(i).unwrap();
        assert!(*l.as_ref::<Position, _>() == v.position);
        assert!(*l.as_ref::<Color, _>() == v.color);
        assert!(*l.as_ref::<Normal, _>() == v.normal);
        assert!(*l.as_ref::<Other, _>() == v.other);
    }
    assert!(lens.get_all(2).is_none());
}

#[allow(clippy::cast_possible_truncation, clippy::cast_precision_loss)]
#[test]
fn lens_slice_mut_get_all_mut() {
    let mut verts = [
        Vertex {
            position: [1.0, 2.0, 3.0],
            color: [4.0, 5.0, 6.0],
            normal: [7, 8],
            other: 0xAA,
        },
        Vertex {
            position: [10.0, 20.0, 30.0],
            color: [40.0, 50.0, 60.0],
            normal: [70, 80],
            other: 0xBB,
        },
    ];
    {
        let mut lens: LensSliceMut<'_, (Normal, Other, Color, Position)> =
            verts.as_mut_slice().lens_slice_mut();

        for i in 0..2 {
            let mut l = lens.get_all_mut(i).unwrap();
            *l.as_mut::<Position, _>() = [200.0 + i as f32, 0.0, 0.0];
            *l.as_mut::<Color, _>() = [100.0 + i as f32, 0.0, 0.0];
            *l.as_mut::<Normal, _>() = [i as u8, (i + 1) as u8];
            *l.as_mut::<Other, _>() = 0x1000 + i as u64;
        }
        assert!(lens.get_all_mut(2).is_none());
    }

    assert!(verts[0].position == [200.0, 0.0, 0.0]);
    assert!(verts[1].position == [201.0, 0.0, 0.0]);
    assert!(verts[0].color == [100.0, 0.0, 0.0]);
    assert!(verts[1].color == [101.0, 0.0, 0.0]);
    assert!(verts[0].normal == [0, 1]);
    assert!(verts[1].normal == [1, 2]);
    assert!(verts[0].other == 0x1000);
    assert!(verts[1].other == 0x1001);
}

#[test]
fn lens_slice_mut_get_all_mut_out_of_bounds() {
    let mut verts: [Vertex; 0] = [];
    let mut lens: LensSliceMut<'_, (Normal, Other, Color, Position)> =
        verts.as_mut_slice().lens_slice_mut();
    assert!(lens.is_empty());
    assert!(lens.get_all_mut(0).is_none());
}

#[allow(clippy::cast_possible_truncation, clippy::cast_precision_loss)]
#[test]
fn lens_slice_mut_get_all_mut_after_split() {
    let mut verts = [
        Vertex {
            position: [1.0, 2.0, 3.0],
            color: [4.0, 5.0, 6.0],
            normal: [7, 8],
            other: 0xAA,
        },
        Vertex {
            position: [10.0, 20.0, 30.0],
            color: [40.0, 50.0, 60.0],
            normal: [70, 80],
            other: 0xBB,
        },
    ];
    {
        let lens: LensSliceMut<'_, (Normal, Other, Color, Position)> =
            verts.as_mut_slice().lens_slice_mut();
        let (mut lhs, mut rhs) = lens.split::<(Position,), _>();

        let mut l = lhs.get_all_mut(0).unwrap();
        *l.as_mut::<Position, _>() = [999.0, 0.0, 0.0];

        let mut r = rhs.get_all_mut(1).unwrap();
        *r.as_mut::<Color, _>() = [888.0, 0.0, 0.0];
        *r.as_mut::<Normal, _>() = [42, 43];
        *r.as_mut::<Other, _>() = 0xFEED;
    }

    assert!(verts[0].position == [999.0, 0.0, 0.0]);
    assert!(verts[1].color == [888.0, 0.0, 0.0]);
    assert!(verts[1].normal == [42, 43]);
    assert!(verts[1].other == 0xFEED);
}