melinoe 0.10.0

Zero-sized, branded, multi-token phantom capabilities for compile-time data-access and thread-synchronization proofs (a generalized evolution of GhostCell) for the Mnemosyne memory ecosystem.
Documentation
//! Conditional `Cow` boundary tests for branded slices.

#![cfg(feature = "alloc")]

use std::borrow::Cow;

use melinoe::{brand_scope, Borrowed, CellCowExt, MelinoeCell, RetainDecision, Retained};

struct NonClone;

fn assert_cell_cow_impl<'brand>()
where
    [MelinoeCell<'brand, NonClone>]: CellCowExt<'brand, NonClone>,
{
}

#[test]
fn cell_cow_trait_boundary_does_not_require_clone() {
    assert_cell_cow_impl();
}

#[test]
fn borrowed_policy_returns_zero_copy_borrow() {
    brand_scope(|token| {
        let cells: Vec<MelinoeCell<'_, u8>> = (0..4).map(MelinoeCell::new).collect();
        let cow = cells.borrow_cow_with(&token, Borrowed);

        match cow {
            Cow::Borrowed(slice) => {
                assert_eq!(slice, &[0, 1, 2, 3]);
                assert_eq!(slice.as_ptr() as usize, cells.as_ptr() as usize);
            }
            Cow::Owned(_) => panic!("Borrowed policy must not clone"),
        }
    });
}

#[test]
fn direct_borrow_cow_is_zero_copy() {
    brand_scope(|token| {
        let cells: Vec<MelinoeCell<'_, u8>> = (4..8).map(MelinoeCell::new).collect();
        let cow = cells.borrow_cow(&token);

        match cow {
            Cow::Borrowed(slice) => {
                assert_eq!(slice, &[4, 5, 6, 7]);
                assert_eq!(slice.as_ptr() as usize, cells.as_ptr() as usize);
            }
            Cow::Owned(_) => panic!("borrow_cow must not clone"),
        }
    });
}

#[test]
fn retained_policy_returns_owned_copy() {
    brand_scope(|token| {
        let cells: Vec<MelinoeCell<'_, u8>> = (0..4).map(MelinoeCell::new).collect();
        let cow = cells.borrow_cow_with(&token, Retained);

        match cow {
            Cow::Borrowed(_) => panic!("Retained policy must clone"),
            Cow::Owned(values) => {
                assert_eq!(values, vec![0, 1, 2, 3]);
                assert_ne!(values.as_ptr() as usize, cells.as_ptr() as usize);
            }
        }
    });
}

#[test]
fn direct_retain_cow_clones_once() {
    brand_scope(|token| {
        let cells: Vec<MelinoeCell<'_, u8>> = (8..12).map(MelinoeCell::new).collect();
        let cow = cells.retain_cow(&token);

        match cow {
            Cow::Borrowed(_) => panic!("retain_cow must clone"),
            Cow::Owned(values) => {
                assert_eq!(values, vec![8, 9, 10, 11]);
                assert_ne!(values.as_ptr() as usize, cells.as_ptr() as usize);
            }
        }
    });
}

#[test]
fn runtime_decision_selects_borrow_or_retain() {
    brand_scope(|token| {
        let cells: Vec<MelinoeCell<'_, u16>> = (10..14).map(MelinoeCell::new).collect();

        let borrowed = cells.borrow_cow_if(&token, RetainDecision::Borrow);
        assert!(matches!(borrowed, Cow::Borrowed(_)));
        assert_eq!(&*borrowed, &[10, 11, 12, 13]);

        let retained = cells.borrow_cow_if(&token, RetainDecision::Retain);
        assert!(matches!(retained, Cow::Owned(_)));
        assert_eq!(&*retained, &[10, 11, 12, 13]);
    });
}