|
|
|
@ -165,26 +165,47 @@ impl Object
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Consume into the data
|
|
|
|
|
#[deprecated = "Invalid ABI"] fn into_bytes(self) -> Box<[u8]>
|
|
|
|
|
pub fn into_bytes(self) -> Box<[u8]>
|
|
|
|
|
{
|
|
|
|
|
let mut output = Vec::new(); //TOOO: Get cap
|
|
|
|
|
|
|
|
|
|
debug_assert!(self.validate(), "passing invalid object to serialise");
|
|
|
|
|
|
|
|
|
|
unsafe {
|
|
|
|
|
output.extend_from_slice(bytes::refer(&self.data_instances.len()));
|
|
|
|
|
for (name, Range{start, end}) in self.data_instances.into_iter() {
|
|
|
|
|
let name = name.as_bytes();
|
|
|
|
|
macro_rules! bin {
|
|
|
|
|
($bytes:expr) => {
|
|
|
|
|
{
|
|
|
|
|
let bytes = $bytes;
|
|
|
|
|
output.extend_from_slice(bytes.as_ref());
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
(usize $value:expr) => {
|
|
|
|
|
{
|
|
|
|
|
use std::convert::TryInto;
|
|
|
|
|
use byteorder::{
|
|
|
|
|
WriteBytesExt,
|
|
|
|
|
LittleEndian,
|
|
|
|
|
};
|
|
|
|
|
let val: u64 = $value.try_into().expect("Value could not fit into `u64`");
|
|
|
|
|
WriteBytesExt::write_u64::<LittleEndian>(&mut output,val).expect("Failed to append `u64` to output buffer");
|
|
|
|
|
|
|
|
|
|
output.extend_from_slice(bytes::refer(&name.len()));
|
|
|
|
|
output.extend_from_slice(name);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
output.extend_from_slice(bytes::refer(&start));
|
|
|
|
|
output.extend_from_slice(bytes::refer(&end));
|
|
|
|
|
}
|
|
|
|
|
bin!(usize self.data_instances.len());
|
|
|
|
|
for (name, &Range{start, end}) in self.data_instances.iter() {
|
|
|
|
|
let name = name.as_bytes();
|
|
|
|
|
|
|
|
|
|
bin!(usize name.len());
|
|
|
|
|
bin!(name);
|
|
|
|
|
|
|
|
|
|
bin!(usize start);
|
|
|
|
|
bin!(usize end);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bin!(usize self.data.len()); //for additional checks
|
|
|
|
|
output.extend(self.data);
|
|
|
|
|
|
|
|
|
|
output.into_boxed_slice()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -329,6 +350,14 @@ impl fmt::Display for Error
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl From<io::Error> for Error
|
|
|
|
|
{
|
|
|
|
|
#[inline] fn from(from: io::Error) -> Self
|
|
|
|
|
{
|
|
|
|
|
Self::IO(from)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// A suspendable type, that can save and reload its data atomically
|
|
|
|
|
#[async_trait]
|
|
|
|
@ -338,11 +367,154 @@ pub trait Suspendable: Sized
|
|
|
|
|
async fn load<S: SuspendStream + Send+ Sync+?Sized>(from: &mut S) -> Result<Self, Error>;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// An in-memory `SuspendStream`.
|
|
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
|
pub struct MemorySsuspendStream(Vec<u8>);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
pub struct SuspenceState<T>
|
|
|
|
|
where T: Suspendable
|
|
|
|
|
impl MemorySsuspendStream
|
|
|
|
|
{
|
|
|
|
|
/// Create a new empty instance
|
|
|
|
|
pub fn new() -> Self
|
|
|
|
|
{
|
|
|
|
|
Self(Vec::new())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Create from a vector of bytes
|
|
|
|
|
pub fn from_bytes(from: impl Into<Vec<u8>>) -> Self
|
|
|
|
|
{
|
|
|
|
|
Self(from.into())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Create from a slice of bytes
|
|
|
|
|
pub fn from_slice(from: impl AsRef<[u8]>) -> Self
|
|
|
|
|
{
|
|
|
|
|
Self(Vec::from(from.as_ref()))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Return the internal bytes
|
|
|
|
|
pub fn into_bytes(self) -> Vec<u8>
|
|
|
|
|
{
|
|
|
|
|
self.0
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// The internal buffer
|
|
|
|
|
pub fn buffer(&self) -> &Vec<u8>
|
|
|
|
|
{
|
|
|
|
|
&self.0
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// The internal buffer
|
|
|
|
|
pub fn buffer_mut(&mut self) -> &mut Vec<u8>
|
|
|
|
|
{
|
|
|
|
|
&mut self.0
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_phantom: PhantomData<T>,
|
|
|
|
|
}*/
|
|
|
|
|
impl AsRef<[u8]> for MemorySsuspendStream
|
|
|
|
|
{
|
|
|
|
|
fn as_ref(&self) -> &[u8]
|
|
|
|
|
{
|
|
|
|
|
&self.0[..]
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl AsMut<[u8]> for MemorySsuspendStream
|
|
|
|
|
{
|
|
|
|
|
fn as_mut(&mut self) -> &mut [u8]
|
|
|
|
|
{
|
|
|
|
|
&mut self.0[..]
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl From<Vec<u8>> for MemorySsuspendStream
|
|
|
|
|
{
|
|
|
|
|
#[inline] fn from(from: Vec<u8>) -> Self
|
|
|
|
|
{
|
|
|
|
|
Self(from.into())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl From<Box<[u8]>> for MemorySsuspendStream
|
|
|
|
|
{
|
|
|
|
|
fn from(from: Box<[u8]>) -> Self
|
|
|
|
|
{
|
|
|
|
|
Self::from_bytes(from)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl From<MemorySsuspendStream> for Box<[u8]>
|
|
|
|
|
{
|
|
|
|
|
fn from(from: MemorySsuspendStream) -> Self
|
|
|
|
|
{
|
|
|
|
|
from.0.into()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl From<MemorySsuspendStream> for Vec<u8>
|
|
|
|
|
{
|
|
|
|
|
#[inline] fn from(from: MemorySsuspendStream) -> Self
|
|
|
|
|
{
|
|
|
|
|
from.0
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[async_trait]
|
|
|
|
|
impl SuspendStream for MemorySsuspendStream
|
|
|
|
|
{
|
|
|
|
|
async fn get_object(&mut self) -> Result<Option<Object>, Error> {
|
|
|
|
|
if self.0.len() ==0 {
|
|
|
|
|
return Ok(None);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let mut ptr = &self.0[..];
|
|
|
|
|
let vl = Object::from_stream(&mut ptr).await?;
|
|
|
|
|
let diff = (ptr.as_ptr() as usize) - ((&self.0[..]).as_ptr() as usize);
|
|
|
|
|
self.0.drain(0..diff);
|
|
|
|
|
|
|
|
|
|
Ok(Some(vl))
|
|
|
|
|
}
|
|
|
|
|
async fn set_object(&mut self, obj: Object) -> Result<(), Error> {
|
|
|
|
|
obj.into_stream(&mut self.0).await?;
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Suspend a single object to memory
|
|
|
|
|
pub async fn oneshot<T: Suspendable>(value: T) -> Result<Vec<u8>, Error>
|
|
|
|
|
{
|
|
|
|
|
let mut output = MemorySsuspendStream::new();
|
|
|
|
|
value.suspend(&mut output).await?;
|
|
|
|
|
Ok(output.into_bytes())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Load a single value from memory
|
|
|
|
|
pub async fn single<T: Suspendable>(from: impl AsRef<[u8]>) -> Result<T, Error>
|
|
|
|
|
{
|
|
|
|
|
struct BorrowedStream<'a>(&'a [u8]);
|
|
|
|
|
|
|
|
|
|
#[async_trait]
|
|
|
|
|
impl<'a> SuspendStream for BorrowedStream<'a>
|
|
|
|
|
{
|
|
|
|
|
async fn get_object(&mut self) -> Result<Option<Object>, Error> {
|
|
|
|
|
if self.0.len() ==0 {
|
|
|
|
|
return Ok(None);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let mut ptr = &self.0[..];
|
|
|
|
|
let vl = Object::from_stream(&mut ptr).await?;
|
|
|
|
|
let diff = (ptr.as_ptr() as usize) - ((&self.0[..]).as_ptr() as usize);
|
|
|
|
|
self.0 = &self.0[diff..];
|
|
|
|
|
|
|
|
|
|
Ok(Some(vl))
|
|
|
|
|
}
|
|
|
|
|
async fn set_object(&mut self, _: Object) -> Result<(), Error> {
|
|
|
|
|
panic!("Cannot write to borrowed stream")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let bytes = from.as_ref();
|
|
|
|
|
let mut stream = BorrowedStream(bytes);
|
|
|
|
|
|
|
|
|
|
T::load(&mut stream).await
|
|
|
|
|
}
|
|
|
|
|