dizzy 0.1.0

Macros for safely interacting with DST newtypes
Documentation
use std::borrow::Cow;

use dizzy::DstNewtype;

const fn slice1_invariant<T>(input: &[T]) -> bool {
    !input.is_empty()
}

/// A non-empty slice.
#[derive(PartialEq, DstNewtype)]
#[repr(transparent)]
#[dizzy(invariant = slice1_invariant, constructor = pub const new)]
#[dizzy(constructor_mut = pub const new_mut)]
#[dizzy(unsafe_constructor_mut = pub const new_mut_unchecked)]
#[dizzy(getter = pub const get)]
#[dizzy(derive(AsRef, Debug, CloneBoxed, IntoBoxed))]
#[dizzy(owned = Vec1(Vec<T>))]
#[dizzy(derive_owned(Debug, IntoBoxed))]
struct Slice1<T> {
    __zst_garbage: (),
    inner: [T],
}

#[test]
fn constructor() {
    assert!(Slice1::<()>::new(&[]).is_none());
    assert!(Slice1::<()>::new(&[()]).is_some());
}

#[test]
fn constructor_mut() {
    let mut buf: Vec<u8> = vec![0, 1, 2, 3, 4, 5, 6, 7, 8];
    let _slice1_mut: &mut Slice1<u8> = Slice1::new_mut(&mut buf).unwrap();
}

#[test]
fn unsafe_constructor_mut() {
    let mut buf: Vec<u8> = vec![0, 1, 2, 3, 4, 5, 6, 7, 8];
    // SAFETY: `buf` is clearly non-empty
    let _slice1_mut = unsafe { Slice1::new_mut_unchecked(&mut buf) };
}

#[test]
fn boxed_impls() {
    let boxed1: Box<Slice1<char>> = Slice1::new(&['a', 'b', 'c', 'd']).unwrap().into();
    let boxed2 = boxed1.clone();
    assert_eq!(boxed1, boxed2);
}

#[test]
fn owned_type() {
    let slice1: &Slice1<i32> = Slice1::new(&[-1, 2, -3, 4, -5, 6, -7, 8, -9, 10]).unwrap();
    let _vec1 = slice1.to_owned();
}

#[test]
fn cow_from_owned() {
    let slice1: &Slice1<i32> = Slice1::new(&[1, 2, 3]).unwrap();
    let vec1: Vec1<i32> = slice1.to_owned();
    let cow: Cow<'_, Slice1<i32>> = Cow::from(&vec1);
    assert!(matches!(cow, Cow::Owned(_)));
    assert_eq!(cow.get(), &[1, 2, 3]);
}

#[test]
fn debug_impls() {
    let slice = Slice1::<u8>::new(b"hello, world!".as_slice()).unwrap();
    let owned = Vec1::from(slice);
    let boxed = Box::<Slice1<u8>>::from(slice);

    // check that all debug impls are equivalent
    assert_eq!(format!("{:?}", slice), format!("{:?}", owned));
    assert_eq!(format!("{:?}", slice), format!("{:?}", boxed));
    assert_eq!(format!("{:?}", owned), format!("{:?}", boxed));
    assert_eq!(boxed, owned.into());
}