use super::keypath::{Keypath, LeafKey};
use crate::StorageKey;
use crate::exn::LibraryExn;
use crate::re_throw::OrReThrow;
use crate::sys_exn::rcq::*;
use crate::xdr::*;
use core::fmt::Debug;
use core::marker::PhantomData;
#[derive(Debug)]
pub struct RCQ<T> {
key: LeafKey,
phantom_entry: PhantomData<fn() -> T>,
}
impl<T> From<Keypath> for RCQ<T> {
fn from(keypath: Keypath) -> Self {
Self {
key: keypath.into(),
phantom_entry: PhantomData,
}
}
}
impl<T> RCQ<T> {
pub fn key(&self) -> &StorageKey {
self.key.get()
}
}
impl<T> RCQ<T> {
pub fn insert_raw(&mut self, queue_entry: &[u8]) {
retrocausal_queue_insert(self.key(), queue_entry);
}
pub fn consume_sized<const N: usize>(&mut self) -> [u8; N] {
retrocausal_queue_consume_sized(self.key())
}
pub fn try_consume_sized<const N: usize>(
&mut self,
) -> Result<[u8; N], LibraryExn> {
retrocausal_queue_try_consume_sized(self.key())
}
#[cfg(feature = "alloc")]
pub fn consume_raw(&mut self) -> alloc::boxed::Box<[u8]> {
self.try_consume_raw().or_re_throw()
}
#[cfg(feature = "alloc")]
pub fn try_consume_raw(
&mut self,
) -> Result<alloc::boxed::Box<[u8]>, LibraryExn> {
retrocausal_queue_try_consume(self.key())
}
pub fn peek_sized<const N: usize>(&self) -> [u8; N] {
retrocausal_queue_peek_sized(self.key())
}
pub fn try_peek_sized<const N: usize>(
&self,
) -> Result<[u8; N], LibraryExn> {
retrocausal_queue_try_peek_sized(self.key())
}
#[cfg(feature = "alloc")]
pub fn peek_raw(&self) -> alloc::boxed::Box<[u8]> {
self.try_peek_raw().or_re_throw()
}
#[cfg(feature = "alloc")]
pub fn try_peek_raw(&self) -> Result<alloc::boxed::Box<[u8]>, LibraryExn> {
retrocausal_queue_try_peek(self.key())
}
}
impl<T> RCQ<T>
where
T: WriteXDR,
{
pub fn insert(&mut self, entry: &T) {
crate::call::with_scratch(|buf| {
crate::internal::encode_scratch(buf, entry)
.unwrap_or_else(|e| super::error::throw_store_exn(e));
self.insert_raw(buf.as_slice());
});
}
}
impl<T> RCQ<T>
where
T: ReadXDROwned,
{
pub fn consume(&mut self) -> T {
self.try_decode_entry(false).or_re_throw()
}
pub fn try_consume(&mut self) -> Result<T, LibraryExn> {
let value = self.try_decode_entry(true)?;
retrocausal_queue_try_discard(self.key())?;
Ok(value)
}
pub fn peek(&self) -> T {
self.try_peek().or_re_throw()
}
pub fn try_peek(&self) -> Result<T, LibraryExn> {
self.try_decode_entry(true)
}
fn try_decode_entry(&self, peek: bool) -> Result<T, LibraryExn> {
crate::call::with_scratch(|buf| {
retrocausal_queue_try_read_into(self.key(), peek, buf)?;
cxs::decode(buf.as_slice())
.map_err(|_| LibraryExn::StorageSerialization)
})
}
}
impl<S> super::sealed::Sealed for RCQ<S> {}
impl<S> super::node::StorageType for RCQ<S> {}
impl<T> super::deletable::Deletable for RCQ<T> {
fn delete_internal(&mut self, exclusive: bool) {
let exclusive = exclusive || self.key.is_exclusive();
crate::sys_exn::delete::delete(self.key(), exclusive);
}
}