use super::*;
use std::convert::TryInto;
use std::fmt::Debug;
const N: usize = 10;
const H: usize = 5;
type Fv<T> = FixedCapacityVec<T, N>;
fn test_api<T: Debug, F: FnMut() -> T>(mut f: F) {
let f = &mut f;
let mk_half = |f: &mut F| {
let mut v = Fv::<T>::new();
assert_eq!(v.len(), 0);
assert!(v.is_empty());
assert!(!v.is_full());
println!("fill 0..{H}");
for i in 0..H {
v.push(f());
assert_eq!(v.len(), i + 1);
}
assert!(!v.is_empty());
assert!(!v.is_full());
v
};
println!("make (1)");
let v = mk_half(f);
println!("fail conversion to boxed array");
let mut v: Fv<T> = Box::<[T; N]>::try_from(v).unwrap_err();
assert_eq!(v.len(), H);
println!("deref");
let slice = &v[..];
println!("{slice:?}");
println!("deref mut");
let slice = &mut v[..];
slice[1] = f();
println!("{slice:?}");
println!("drop 0..{H}");
drop(v);
println!("make empty (2)");
let mut v = Fv::<T>::new();
println!("fill 0..{N}");
for _i in 0..N {
v.push(f());
}
let FullError = v.try_push_or_discard(f()).unwrap_err();
assert_eq!(v.len(), N);
assert!(v.is_full());
assert!(!v.is_empty());
println!("conversion to boxed array");
let v: Box<[T; N]> = v.try_into().expect("not into boxed array");
println!("drop boxed array");
drop(v);
println!("conversion from boxed array");
let ba = Box::new([f(), f()]);
let v = FixedCapacityVec::from(ba);
assert!(v.is_full());
println!("{v:?}");
drop(v);
println!("conversion to Vec");
let v = mk_half(f);
let v: Vec<T> = v.into();
println!("{v:?}");
drop(v);
println!("failed conversion from Vec");
let mut v = vec![f(), f()];
v.shrink_to_fit();
let mut v: Vec<T> = match Fv::<T>::try_from(v) {
Err(fail) => fail,
Ok(_v) if Layout::new::<T>().size() == 0 => {
vec![f(), f()]
}
Ok(y) => panic!("{:?}", y),
};
println!("successful conversion from Vec");
v.reserve_exact(
N.saturating_sub(v.capacity()),
);
let v: Fv<T> = v.try_into().unwrap();
println!("{:?}", &v[..]);
drop(v);
println!("try_push");
let mut v = mk_half(f);
let rejected = loop {
match v.try_push(f()) {
Ok(()) => {}
Err(n) => break n,
}
};
println!("rejected {rejected:?}");
drop(v);
println!("pop");
let mut v = mk_half(f);
while let Some(item) = v.pop() {
println!("popped {item:?}");
}
drop(v);
}
fn test_api_nopush<T: Debug, const N: usize>() {
let v = FixedCapacityVec::<T, N>::new();
assert_eq!(v.len(), 0);
assert!(v.is_empty());
if N == 0 {
assert!(v.is_full());
println!("successful conversion to boxed array");
let v = FixedCapacityVec::<T, N>::new();
let v = Box::<[T; N]>::try_from(v)
.map_err(|_| ())
.expect("not into boxed 0 slice");
assert_eq!(v.len(), 0);
} else {
assert!(!v.is_full());
}
}
#[test]
fn api_i32() {
test_api(|| 42_i32);
}
use std::cell::RefCell;
use std::rc::Rc;
#[derive(Debug)]
struct HasDrop {
index: usize,
counted: Rc<RefCell<usize>>,
}
impl Drop for HasDrop {
fn drop(&mut self) {
println!("dropping {}", self.index);
*self.counted.borrow_mut() -= 1;
}
}
#[test]
fn zst() {
test_api(|| ());
test_api_nopush::<(), 0>();
test_api_nopush::<(), 1>();
test_api_nopush::<u32, 0>();
#[derive(Debug)]
enum Never {}
test_api_nopush::<Never, 0>();
test_api_nopush::<Never, 1>();
}
#[test]
fn api_has_drop() {
let counted = Rc::new(RefCell::new(0));
let mut next_index = 0;
test_api(|| {
let index = {
let mut counted = counted.borrow_mut();
*counted += 1;
next_index += 1;
next_index
};
println!("creating {}", index);
HasDrop {
index,
counted: counted.clone(),
}
});
assert_eq!(*counted.borrow(), 0);
}