trait-obj-list 0.1.2

List of unsized trait objects, stored in a flat array
Documentation
#[path = "../src/test_utils.rs"]
mod utils;

use std::any::Any;
use std::mem::MaybeUninit;

use trait_obj_list::DynList;

utils::for_each_list_type! {
	#[test]
	fn test_push_box<T>() {
		let mut l = DynList::<dyn Any, T>::new();
		assert!(l.is_empty());
		l.push_boxed(Box::new(123i32) as Box<dyn Any>);
		l.push_boxed(Box::new(456u64) as Box<dyn Any>);
		l.push_boxed(Box::new(7i32) as Box<dyn Any>);
		assert!(!l.is_empty());

		let mut it = l.iter();
		let i1 = it.next().unwrap();
		let i2 = it.next().unwrap();
		let i3 = it.next().unwrap();
		assert!(it.next().is_none());

		assert_eq!(i1.downcast_ref::<i32>().copied(), Some(123));
		assert_eq!(i1.downcast_ref::<u64>().copied(), None);
		assert_eq!(i2.downcast_ref::<u64>().copied(), Some(456));
		assert_eq!(i2.downcast_ref::<i32>().copied(), None);
		assert_eq!(i3.downcast_ref::<i32>().copied(), Some(7));
		assert_eq!(i3.downcast_ref::<u64>().copied(), None);

		core::mem::drop(l);
	}

	#[test]
	fn test_push_ptr<T>() {
		let mut l = DynList::<dyn Any, T>::new();
		assert!(l.is_empty());

		fn push_from_ptr<U: Any>(list: &mut DynList<dyn Any, T>, v: U) {
			let mut v = MaybeUninit::new(v);
			let p = v.as_mut_ptr() as *mut dyn Any;
			unsafe { list.push_ptr(p) }
		}

		push_from_ptr(&mut l, 123i32);
		push_from_ptr(&mut l, 456u64);
		push_from_ptr(&mut l, 7i32);
		assert!(!l.is_empty());

		let mut it = l.iter();
		let i1 = it.next().unwrap();
		let i2 = it.next().unwrap();
		let i3 = it.next().unwrap();
		assert!(it.next().is_none());

		assert_eq!(i1.downcast_ref::<i32>().copied(), Some(123));
		assert_eq!(i1.downcast_ref::<u64>().copied(), None);
		assert_eq!(i2.downcast_ref::<u64>().copied(), Some(456));
		assert_eq!(i2.downcast_ref::<i32>().copied(), None);
		assert_eq!(i3.downcast_ref::<i32>().copied(), Some(7));
		assert_eq!(i3.downcast_ref::<u64>().copied(), None);

		core::mem::drop(l);
	}

	#[test]
	fn extend_from_other<T>() {
		let mut l1 = DynList::<dyn Any, T>::new();
		let mut l2 = DynList::<dyn Any, trait_obj_list::types::SingleLinked>::new();
		let mut l3 = DynList::<dyn Any, trait_obj_list::types::DoubleLinked>::new();

		l1.extend([1,2,3i32]);
		l2.extend([4,5,6i64]);
		l3.extend([7i8, 8i8]);
		l1.extend_from_other(l2);
		l1.extend_from_other(l3);

		assert_eq!(l1.len(), 8);
		let mut it = l1.iter();
		utils::assert_any_eq(it.next().unwrap(), 1i32);
		utils::assert_any_eq(it.next().unwrap(), 2i32);
		utils::assert_any_eq(it.next().unwrap(), 3i32);
		utils::assert_any_eq(it.next().unwrap(), 4i64);
		utils::assert_any_eq(it.next().unwrap(), 5i64);
		utils::assert_any_eq(it.next().unwrap(), 6i64);
		utils::assert_any_eq(it.next().unwrap(), 7i8);
		utils::assert_any_eq(it.next().unwrap(), 8i8);
		assert!(it.next().is_none());
	}
}