use std::marker;
use crate::{
buffer,
buffer::{bytes::scope, pool, pool::owners, resident, storage},
mem::rc,
};
#[repr(transparent)]
pub struct Owner<'id, S> {
pub(in crate::buffer::bytes::scope) storage: S,
pub(in crate::buffer::bytes::scope) brand: marker::PhantomData<*mut &'id ()>,
}
impl<'id, S: buffer::raw::Source> Owner<'id, S> {
pub fn view(&self) -> scope::View<'_, 'id> {
scope::View {
bytes: self.storage.as_ref(),
brand: self.brand,
}
}
}
impl<'a, 'id, S: buffer::raw::Source + ?Sized> Owner<'id, &'a S> {
pub fn borrow(&self) -> scope::View<'a, 'id> {
scope::View {
bytes: self.storage.as_ref(),
brand: self.brand,
}
}
}
impl<'id, S: buffer::raw::Store> Owner<'id, &mut S> {
pub fn borrow(&self) -> scope::View<'_, 'id> {
scope::View {
bytes: self.storage.as_ref(),
brand: self.brand,
}
}
}
impl<'id, 'd> Owner<'id, resident::Shared<'d>> {
pub fn try_clone(&self) -> Result<Self, rc::Error> {
Ok(Self {
storage: self.storage.try_clone()?,
brand: self.brand,
})
}
}
impl<S> Owner<'_, S> {
pub fn with<T>(storage: S, run: impl for<'id> FnOnce(Owner<'id, S>) -> T) -> T {
run(Owner {
storage,
brand: marker::PhantomData,
})
}
pub fn into_inner(self) -> S {
self.storage
}
}
impl<'id, L> Owner<'id, pool::Span<owners::Plain<L>, pool::Owned, pool::Frozen>> {
pub fn into_shared(self) -> Owner<'id, storage::Shared> {
Owner {
storage: self.storage.into_shared(),
brand: self.brand,
}
}
}
impl<'id, S: buffer::raw::Store> Owner<'id, S> {
pub fn project(mut self, range: scope::Range<'id>) -> S {
S::project(unsafe { buffer::raw::Slice::from_parts(&mut self.storage, range) });
self.storage
}
}
impl<S: AsRef<[u8]>> AsRef<[u8]> for Owner<'_, S> {
fn as_ref(&self) -> &[u8] {
self.storage.as_ref()
}
}
const _: () = {
assert!(
size_of::<Owner<'static, pool::Span<owners::Plain<pool::Layout>, pool::Owned, pool::Frozen>>>(
) == size_of::<pool::Span<owners::Plain<pool::Layout>, pool::Owned, pool::Frozen>>()
);
assert!(
size_of::<
Option<
Owner<'static, pool::Span<owners::Plain<pool::Layout>, pool::Owned, pool::Frozen>>,
>,
>() == size_of::<Option<pool::Span<owners::Plain<pool::Layout>, pool::Owned, pool::Frozen>>>(
)
);
assert!(size_of::<Owner<'static, storage::Shared>>() == size_of::<storage::Shared>());
};