use std::{num::NonZero, ops};
use o3::{
buffer,
buffer::{
Complete as _,
bytes::bounded::Value,
hold, resident, storage,
storage::{provided, range},
write::{consume, consume::Consume},
},
};
use crate::io::{recv, transfer, transfer::Length as _};
pub type Shared<'d> = Value<storage::Shared<provided::Owner<'d>>>;
const _: () = {
assert!(size_of::<Shared<'static>>() == 3 * size_of::<usize>());
};
#[repr(transparent)]
pub struct Lease<'d>(Value<provided::Unique<'d>>);
impl<'d> Lease<'d> {
pub(crate) fn new(buffer: Value<provided::Unique<'d>>) -> Self {
Self(buffer)
}
pub fn as_slice(&self) -> &[u8] {
self.0.as_ref()
}
pub fn as_mut_slice(&mut self) -> &mut [u8] {
self.0.as_mut()
}
pub fn len(&self) -> transfer::Len {
self.0.len()
}
pub(in crate::io) fn into_inner(self) -> Value<provided::Unique<'d>> {
self.0
}
pub fn into_shared(self) -> recv::Shared<'d> {
self.into()
}
}
impl AsRef<[u8]> for Lease<'_> {
fn as_ref(&self) -> &[u8] {
self.0.as_ref()
}
}
impl transfer::Length for Lease<'_> {
fn len(&self) -> transfer::Len {
self.0.len()
}
}
unsafe impl buffer::raw::Consume for Lease<'_> {
fn consume<const MAX: u32>(prefix: buffer::raw::Consumed<'_, '_, Self, MAX>) {
Value::<provided::Unique>::consume(unsafe { prefix.map(|owner| &mut owner.0) });
}
}
impl Consume for Lease<'_> {
fn remaining(&self) -> usize {
self.as_slice().len()
}
fn try_consume(&mut self, amount: usize) -> Result<(), consume::Error> {
self.0.try_consume(amount)
}
fn consume_max(&mut self, max: usize) -> usize {
self.0.consume_max(max)
}
}
const _: () = {
assert!(size_of::<Lease<'static>>() == 3 * size_of::<usize>());
};
impl<'d> provided::Mutable<'d> for Lease<'d> {
type Account = Value<storage::Shared<Option<provided::Account<'d>>>>;
type Frozen = recv::Shared<'d>;
type Prefix<'a>
= Value<provided::Prefix<'a, 'd>>
where
Self: 'a;
fn try_take(&mut self, amount: NonZero<usize>) -> Result<Self::Prefix<'_>, consume::Error> {
self.0.try_take(amount)
}
}
impl<'d> From<Lease<'d>> for Shared<'d> {
fn from(lease: Lease<'d>) -> Self {
lease.0.into()
}
}
impl AsMut<[u8]> for Lease<'_> {
fn as_mut(&mut self) -> &mut [u8] {
self.0.as_mut()
}
}
impl<'d> buffer::Source for Lease<'d> {
type View<'input>
= Value<&'input [u8]>
where
Self: 'input;
fn remaining(&self) -> usize {
self.0.as_ref().len()
}
}
unsafe impl<'d> hold::raw::Retain<'d> for Lease<'d> {
fn try_copy<'a>(
plan: &Self::View<'a>,
budget: &resident::Budget<'d>,
) -> Result<storage::Owned<resident::Budget<'d>>, hold::Error>
where
Self: 'a,
{
Ok(storage::Owned::try_copy(plan, budget)?)
}
}
impl<'d> buffer::Cursor for Lease<'d> {
fn try_get<'input>(
&'input self,
range: ops::Range<usize>,
) -> Result<Self::View<'input>, range::Error> {
self.0.view().try_get(range)
}
}
impl<'d> buffer::Complete for Lease<'d> {
fn view(&self) -> Self::View<'_> {
self.0.view()
}
}
impl<'d> ops::Deref for Lease<'d> {
type Target = Value<provided::Unique<'d>>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
mod raw;