use std::{
mem, ptr,
sync::{
atomic::{AtomicBool, Ordering},
Arc,
},
};
use arc_slice::{layout::BoxedSliceLayout, ArcBytes};
#[test]
fn empty_vec_subslices() {
let mut bytes = ArcBytes::<BoxedSliceLayout>::from(vec![0, 1, 2, 3]);
let clone1 = bytes.split_to(0);
assert_eq!(clone1.as_ptr(), bytes.as_ptr());
let clone2 = bytes.split_off(bytes.len());
assert_eq!(clone2.as_ptr(), bytes[bytes.len()..].as_ptr());
let clone3 = bytes.subslice(1..1);
assert_eq!(clone3.as_ptr(), bytes[1..].as_ptr());
let mut clone4 = bytes.split_off(0);
assert_eq!(bytes.as_ptr(), bytes[..].as_ptr());
mem::swap(&mut clone4, &mut bytes);
let mut clone5 = bytes.split_to(bytes.len());
assert_eq!(bytes.as_ptr(), bytes[..].as_ptr());
mem::swap(&mut clone5, &mut bytes);
assert_eq!(bytes.try_into_buffer::<Vec<u8>>().unwrap(), [0, 1, 2, 3]);
}
#[test]
fn into_vec() {
let vec = vec![0, 1, 2, 3];
let vec_ptr = vec.as_ptr();
let bytes = ArcBytes::<BoxedSliceLayout>::from(vec);
let vec = bytes.try_into_buffer::<Vec<u8>>().unwrap();
assert_eq!(vec.as_ptr(), vec_ptr);
let mut bytes = ArcBytes::<BoxedSliceLayout>::from(vec);
bytes.advance(2);
let vec = bytes.try_into_buffer::<Vec<u8>>().unwrap();
assert_eq!(vec, [2, 3]);
assert_eq!(vec.as_ptr(), vec_ptr);
let mut bytes = ArcBytes::<BoxedSliceLayout>::from(vec);
bytes.truncate(1);
let vec = bytes.try_into_buffer::<Vec<u8>>().unwrap();
assert_eq!(vec, [2]);
assert_eq!(vec.as_ptr(), vec_ptr);
}
#[derive(Default, Clone)]
struct Metadata {
dropped: Arc<AtomicBool>,
}
impl Drop for Metadata {
fn drop(&mut self) {
self.dropped.store(true, Ordering::Relaxed);
}
}
#[test]
fn metadata() {
let metadata = Metadata::default();
let bytes = ArcBytes::<BoxedSliceLayout>::from_buffer_with_metadata(vec![42], metadata.clone());
assert!(bytes.metadata::<()>().is_none());
assert!(bytes.metadata::<Metadata>().is_some());
let clone = bytes.clone();
assert!(clone.metadata::<()>().is_none());
assert!(clone.metadata::<Metadata>().is_some());
assert!(ptr::eq(
bytes.metadata::<Metadata>().unwrap(),
clone.metadata::<Metadata>().unwrap()
));
assert!(!metadata.dropped.load(Ordering::Relaxed));
drop(bytes);
drop(clone);
assert!(metadata.dropped.load(Ordering::Relaxed));
}