blob: 7211e46ffad134cc59eb6e01adb3af1f40e842e7 [file] [log] [blame]
// This file is part of ICU4X. For terms of use, please see the file
// called LICENSE at the top level of the ICU4X source tree
// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).
// This test is a duplicate of one of the doctests, but is written separately
// since `cargo miri test` doesn't work on doctests yet
use std::borrow::Cow;
use std::mem;
use std::rc::Rc;
use yoke::{Yoke, Yokeable};
fn load_from_cache(_filename: &str) -> Rc<[u8]> {
// dummy implementation
Rc::new([0x5, 0, 0, 0, 0, 0, 0, 0, 0x68, 0x65, 0x6c, 0x6c, 0x6f])
}
fn load_object(filename: &str) -> Yoke<Bar<'static>, Rc<[u8]>> {
let rc: Rc<[u8]> = load_from_cache(filename);
Yoke::<Bar<'static>, Rc<[u8]>>::attach_to_cart(rc, |data: &[u8]| {
// A real implementation would properly deserialize `Bar` as a whole
Bar {
numbers: Cow::Borrowed(bincode::deserialize(data).unwrap()),
string: Cow::Borrowed(bincode::deserialize(data).unwrap()),
owned: Vec::new(),
}
})
}
// also implements Yokeable
struct Bar<'a> {
numbers: Cow<'a, [u8]>,
string: Cow<'a, str>,
owned: Vec<u8>,
}
unsafe impl<'a> Yokeable<'a> for Bar<'static> {
type Output = Bar<'a>;
#[inline]
fn transform(&'a self) -> &'a Bar<'a> {
self
}
#[inline]
fn transform_owned(self) -> Bar<'a> {
self
}
#[inline]
unsafe fn make(from: Bar<'a>) -> Self {
let ret = mem::transmute_copy(&from);
mem::forget(from);
ret
}
#[inline]
fn transform_mut<F>(&'a mut self, f: F)
where
F: 'static + FnOnce(&'a mut Self::Output),
{
unsafe { f(mem::transmute(self)) }
}
}
#[test]
fn test_load() {
// `load_object()` deserializes an object from a file
let mut bar = load_object("filename.bincode");
assert_eq!(bar.get().string, "hello");
assert!(matches!(bar.get().string, Cow::Borrowed(_)));
assert_eq!(&*bar.get().numbers, &[0x68, 0x65, 0x6c, 0x6c, 0x6f]);
assert!(matches!(bar.get().numbers, Cow::Borrowed(_)));
assert_eq!(&*bar.get().owned, &[]);
bar.with_mut(|bar| {
bar.string.to_mut().push_str(" world");
bar.owned.extend_from_slice(&[1, 4, 1, 5, 9]);
});
assert_eq!(bar.get().string, "hello world");
assert!(matches!(bar.get().string, Cow::Owned(_)));
assert_eq!(&*bar.get().owned, &[1, 4, 1, 5, 9]);
// Unchanged and still Cow::Borrowed
assert_eq!(&*bar.get().numbers, &[0x68, 0x65, 0x6c, 0x6c, 0x6f]);
assert!(matches!(bar.get().numbers, Cow::Borrowed(_)));
}