use crate::{traits::*, types::*};
#[cfg(not(feature = "std"))]
use alloc::{boxed::Box, collections::*, string::String, vec::Vec};
#[cfg(not(feature = "std"))]
use core::{marker, mem::MaybeUninit, slice};
#[cfg(feature = "std")]
use std::{collections::*, marker, mem::MaybeUninit, slice};
static MAX_PREALLOCATED_CAPACITY: usize = 4096;
macro_rules! repeat_macro {
($f:ident, $n:expr) => ($f!($n););
($f:ident, $n:expr, $($ns:expr),*) => {
$f!($n);
repeat_macro!($f, $($ns),*);
};
}
impl<X: Serial, Y: Serial> Serial for (X, Y) {
fn serial<W: Write>(&self, out: &mut W) -> Result<(), W::Err> {
self.0.serial(out)?;
self.1.serial(out)
}
}
impl<X: Deserial, Y: Deserial> Deserial for (X, Y) {
fn deserial<R: Read>(source: &mut R) -> ParseResult<Self> {
let x = X::deserial(source)?;
let y = Y::deserial(source)?;
Ok((x, y))
}
}
impl Serial for u8 {
fn serial<W: Write>(&self, out: &mut W) -> Result<(), W::Err> { out.write_u8(*self) }
}
impl Deserial for u8 {
fn deserial<R: Read>(source: &mut R) -> ParseResult<Self> { source.read_u8() }
}
impl Serial for u16 {
fn serial<W: Write>(&self, out: &mut W) -> Result<(), W::Err> { out.write_u16(*self) }
}
impl Deserial for u16 {
fn deserial<R: Read>(source: &mut R) -> ParseResult<Self> { source.read_u16() }
}
impl Serial for u32 {
fn serial<W: Write>(&self, out: &mut W) -> Result<(), W::Err> { out.write_u32(*self) }
}
impl Deserial for u32 {
fn deserial<R: Read>(source: &mut R) -> ParseResult<Self> { source.read_u32() }
}
impl Serial for u64 {
fn serial<W: Write>(&self, out: &mut W) -> Result<(), W::Err> { out.write_u64(*self) }
}
impl Deserial for u64 {
fn deserial<R: Read>(source: &mut R) -> ParseResult<Self> { source.read_u64() }
}
impl Serial for i8 {
fn serial<W: Write>(&self, out: &mut W) -> Result<(), W::Err> { out.write_i8(*self) }
}
impl Deserial for i8 {
fn deserial<R: Read>(source: &mut R) -> ParseResult<Self> { source.read_i8() }
}
impl Serial for i16 {
fn serial<W: Write>(&self, out: &mut W) -> Result<(), W::Err> { out.write_i16(*self) }
}
impl Deserial for i16 {
fn deserial<R: Read>(source: &mut R) -> ParseResult<Self> { source.read_i16() }
}
impl Serial for i32 {
fn serial<W: Write>(&self, out: &mut W) -> Result<(), W::Err> { out.write_i32(*self) }
}
impl Deserial for i32 {
fn deserial<R: Read>(source: &mut R) -> ParseResult<Self> { source.read_i32() }
}
impl Serial for i64 {
fn serial<W: Write>(&self, out: &mut W) -> Result<(), W::Err> { out.write_i64(*self) }
}
impl Deserial for i64 {
fn deserial<R: Read>(source: &mut R) -> ParseResult<Self> { source.read_i64() }
}
impl Serial for bool {
fn serial<W: Write>(&self, out: &mut W) -> Result<(), W::Err> {
if *self {
out.write_u8(1)?;
} else {
out.write_u8(0)?;
}
Ok(())
}
}
impl Deserial for bool {
fn deserial<R: Read>(source: &mut R) -> ParseResult<Self> {
let b = source.read_u8()?;
match b {
0 => Ok(false),
1 => Ok(true),
_ => Err(ParseError::default()),
}
}
}
impl Serial for Amount {
fn serial<W: Write>(&self, out: &mut W) -> Result<(), W::Err> { out.write_u64(self.micro_gtu) }
}
impl Deserial for Amount {
fn deserial<R: Read>(source: &mut R) -> ParseResult<Self> {
source.read_u64().map(Amount::from_micro_gtu)
}
}
impl Serial for Timestamp {
fn serial<W: Write>(&self, out: &mut W) -> Result<(), W::Err> {
self.timestamp_millis().serial(out)
}
}
impl Deserial for Timestamp {
fn deserial<R: Read>(source: &mut R) -> ParseResult<Self> {
u64::deserial(source).map(Timestamp::from_timestamp_millis)
}
}
impl Serial for Duration {
fn serial<W: Write>(&self, out: &mut W) -> Result<(), W::Err> { self.millis().serial(out) }
}
impl Deserial for Duration {
fn deserial<R: Read>(source: &mut R) -> ParseResult<Self> {
u64::deserial(source).map(Duration::from_millis)
}
}
impl Serial for String {
fn serial<W: Write>(&self, out: &mut W) -> Result<(), W::Err> {
self.bytes().collect::<Vec<_>>().serial(out)
}
}
impl Deserial for String {
fn deserial<R: Read>(source: &mut R) -> ParseResult<Self> {
let bytes = Vec::deserial(source)?;
let res = String::from_utf8(bytes).map_err(|_| ParseError::default())?;
Ok(res)
}
}
impl<T: Serial> Serial for Box<T> {
fn serial<W: Write>(&self, out: &mut W) -> Result<(), W::Err> { self.as_ref().serial(out) }
}
impl<T: Deserial> Deserial for Box<T> {
fn deserial<R: Read>(source: &mut R) -> ParseResult<Self> {
let t = T::deserial(source)?;
Ok(Box::new(t))
}
}
impl<C: ?Sized> Serial for marker::PhantomData<C> {
fn serial<W: Write>(&self, _out: &mut W) -> Result<(), W::Err> { Ok(()) }
}
impl<C: ?Sized> Deserial for marker::PhantomData<C> {
fn deserial<R: Read>(_source: &mut R) -> ParseResult<Self> {
Ok(marker::PhantomData::default())
}
}
impl<T: Serial> Serial for Option<T> {
fn serial<W: Write>(&self, out: &mut W) -> Result<(), W::Err> {
match self {
None => out.write_u8(0),
Some(t) => {
out.write_u8(1)?;
t.serial(out)
}
}
}
}
impl<T: Deserial> Deserial for Option<T> {
fn deserial<R: Read>(source: &mut R) -> ParseResult<Self> {
let idx: u8 = source.get()?;
match idx {
0 => Ok(None),
1 => {
let t = T::deserial(source)?;
Ok(Some(t))
}
_ => Err(ParseError::default()),
}
}
}
impl Serial for AccountAddress {
fn serial<W: Write>(&self, out: &mut W) -> Result<(), W::Err> { out.write_all(&self.0) }
}
impl Deserial for AccountAddress {
fn deserial<R: Read>(source: &mut R) -> ParseResult<Self> {
let bytes = {
let mut bytes: MaybeUninit<[u8; 32]> = MaybeUninit::uninit();
let write_bytes =
unsafe { slice::from_raw_parts_mut(bytes.as_mut_ptr() as *mut u8, 32) };
source.read_exact(write_bytes)?;
unsafe { bytes.assume_init() }
};
Ok(AccountAddress(bytes))
}
}
impl Serial for ContractAddress {
fn serial<W: Write>(&self, out: &mut W) -> Result<(), W::Err> {
out.write_u64(self.index)?;
out.write_u64(self.subindex)
}
}
impl Deserial for ContractAddress {
fn deserial<R: Read>(source: &mut R) -> ParseResult<Self> {
let index = source.get()?;
let subindex = source.get()?;
Ok(ContractAddress {
index,
subindex,
})
}
}
impl Serial for Address {
fn serial<W: Write>(&self, out: &mut W) -> Result<(), W::Err> {
match self {
Address::Account(ref acc) => {
out.write_u8(0)?;
acc.serial(out)
}
Address::Contract(ref cnt) => {
out.write_u8(1)?;
cnt.serial(out)
}
}
}
}
impl Deserial for Address {
fn deserial<R: Read>(source: &mut R) -> ParseResult<Self> {
let tag = u8::deserial(source)?;
match tag {
0 => Ok(Address::Account(source.get()?)),
1 => Ok(Address::Contract(source.get()?)),
_ => Err(ParseError::default()),
}
}
}
impl Serial for ChainMetadata {
fn serial<W: Write>(&self, out: &mut W) -> Result<(), W::Err> { self.slot_time.serial(out) }
}
impl Deserial for ChainMetadata {
fn deserial<R: Read>(source: &mut R) -> ParseResult<Self> {
let slot_time = source.get()?;
Ok(Self {
slot_time,
})
}
}
pub fn serial_vector_no_length<W: Write, T: Serial>(xs: &[T], out: &mut W) -> Result<(), W::Err> {
for x in xs {
x.serial(out)?;
}
Ok(())
}
pub fn deserial_vector_no_length<R: Read, T: Deserial>(
reader: &mut R,
len: usize,
) -> ParseResult<Vec<T>> {
let mut vec = Vec::with_capacity(core::cmp::min(len, MAX_PREALLOCATED_CAPACITY));
for _ in 0..len {
vec.push(T::deserial(reader)?);
}
Ok(vec)
}
pub fn serial_map_no_length<'a, W: Write, K: Serial + 'a, V: Serial + 'a>(
map: &BTreeMap<K, V>,
out: &mut W,
) -> Result<(), W::Err> {
for (k, v) in map.iter() {
k.serial(out)?;
v.serial(out)?;
}
Ok(())
}
pub fn deserial_map_no_length<R: Read, K: Deserial + Ord + Copy, V: Deserial>(
source: &mut R,
len: usize,
) -> ParseResult<BTreeMap<K, V>> {
let mut out = BTreeMap::new();
let mut x = None;
for _ in 0..len {
let k = source.get()?;
let v = source.get()?;
match x {
None => {
out.insert(k, v);
}
Some(kk) => {
if k > kk {
out.insert(k, v);
} else {
return Err(ParseError::default());
}
}
}
x = Some(k);
}
Ok(out)
}
pub fn deserial_map_no_length_no_order_check<R: Read, K: Deserial + Ord, V: Deserial>(
source: &mut R,
len: usize,
) -> ParseResult<BTreeMap<K, V>> {
let mut out = BTreeMap::new();
for _ in 0..len {
let k = source.get()?;
let v = source.get()?;
if out.insert(k, v).is_some() {
return Err(ParseError::default());
}
}
Ok(out)
}
pub fn serial_set_no_length<'a, W: Write, K: Serial + 'a>(
map: &BTreeSet<K>,
out: &mut W,
) -> Result<(), W::Err> {
for k in map.iter() {
k.serial(out)?;
}
Ok(())
}
pub fn deserial_set_no_length<R: Read, K: Deserial + Ord + Copy>(
source: &mut R,
len: usize,
) -> ParseResult<BTreeSet<K>> {
let mut out = BTreeSet::new();
let mut prev = None;
for _ in 0..len {
let key = source.get()?;
let next = Some(key);
if next <= prev {
return Err(ParseError::default());
}
out.insert(key);
prev = next;
}
Ok(out)
}
pub fn deserial_set_no_length_no_order_check<R: Read, K: Deserial + Ord>(
source: &mut R,
len: usize,
) -> ParseResult<BTreeSet<K>> {
let mut out = BTreeSet::new();
for _ in 0..len {
let key = source.get()?;
if !out.insert(key) {
return Err(ParseError::default());
}
}
Ok(out)
}
impl<T: Serial> Serial for Vec<T> {
fn serial<W: Write>(&self, out: &mut W) -> Result<(), W::Err> {
let len = self.len() as u32;
len.serial(out)?;
serial_vector_no_length(self, out)
}
}
impl<T: Deserial> Deserial for Vec<T> {
fn deserial<R: Read>(source: &mut R) -> ParseResult<Self> {
let len: u32 = source.get()?;
deserial_vector_no_length(source, len as usize)
}
}
impl<K: Serial + Ord, V: Serial> Serial for BTreeMap<K, V> {
fn serial<W: Write>(&self, out: &mut W) -> Result<(), W::Err> {
let len = self.len() as u32;
len.serial(out)?;
serial_map_no_length(self, out)
}
}
impl<K: Deserial + Ord, V: Deserial> Deserial for BTreeMap<K, V> {
fn deserial<R: Read>(source: &mut R) -> ParseResult<Self> {
let len: u32 = source.get()?;
deserial_map_no_length_no_order_check(source, len as usize)
}
}
impl<K: Serial + Ord> Serial for BTreeSet<K> {
fn serial<W: Write>(&self, out: &mut W) -> Result<(), W::Err> {
let len = self.len() as u32;
len.serial(out)?;
serial_set_no_length(self, out)
}
}
impl<K: Deserial + Ord> Deserial for BTreeSet<K> {
fn deserial<R: Read>(source: &mut R) -> ParseResult<Self> {
let len: u32 = source.get()?;
deserial_set_no_length_no_order_check(source, len as usize)
}
}
macro_rules! serialize_array_x {
($x:expr) => {
impl<T: Serial> Serial for [T; $x] {
fn serial<W: Write>(&self, out: &mut W) -> Result<(), W::Err> {
for elem in self.iter() {
elem.serial(out)?;
}
Ok(())
}
}
impl<T: Deserial> Deserial for [T; $x] {
fn deserial<R: Read>(source: &mut R) -> ParseResult<Self> {
let mut data: MaybeUninit<[T; $x]> = MaybeUninit::uninit();
let ptr = data.as_mut_ptr();
for i in 0..$x {
let item = T::deserial(source)?;
unsafe { (*ptr)[i] = item };
}
Ok(unsafe { data.assume_init() })
}
}
};
}
repeat_macro!(
serialize_array_x,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
31,
32
);
impl Address {
pub fn matches_account(&self, acc: &AccountAddress) -> bool {
if let Address::Account(ref my_acc) = self {
my_acc == acc
} else {
false
}
}
pub fn matches_contract(&self, cnt: &ContractAddress) -> bool {
if let Address::Contract(ref my_cnt) = self {
my_cnt == cnt
} else {
false
}
}
}
impl Serial for AttributeTag {
fn serial<W: Write>(&self, out: &mut W) -> Result<(), W::Err> { self.0.serial(out) }
}
impl Deserial for AttributeTag {
fn deserial<R: Read>(source: &mut R) -> ParseResult<Self> { Ok(AttributeTag(source.get()?)) }
}
impl Serial for OwnedPolicy {
fn serial<W: Write>(&self, out: &mut W) -> Result<(), W::Err> {
self.identity_provider.serial(out)?;
self.created_at.serial(out)?;
self.valid_to.serial(out)?;
(self.items.len() as u16).serial(out)?;
for item in self.items.iter() {
item.0.serial(out)?;
(item.1.len() as u8).serial(out)?;
out.write_all(&item.1)?;
}
Ok(())
}
}
impl Deserial for OwnedPolicy {
fn deserial<R: Read>(source: &mut R) -> ParseResult<Self> {
let identity_provider = source.get()?;
let created_at = source.get()?;
let valid_to = source.get()?;
let len: u16 = source.get()?;
let mut items = Vec::with_capacity(len as usize);
let mut buf = [0u8; 31];
for _ in 0..len {
let tag = AttributeTag::deserial(source)?;
let value_len: u8 = source.get()?;
if value_len > 31 {
return Err(ParseError {});
}
let value_len = usize::from(value_len);
source.read_exact(&mut buf[0..value_len])?;
items.push((tag, buf[0..value_len].to_vec()))
}
Ok(Self {
identity_provider,
created_at,
valid_to,
items,
})
}
}
impl<T> Cursor<T> {
pub fn new(data: T) -> Self {
Cursor {
offset: 0,
data,
}
}
}
impl<T: AsRef<[u8]>> Read for Cursor<T> {
fn read(&mut self, buf: &mut [u8]) -> ParseResult<usize> {
let mut len = self.data.as_ref().len() - self.offset;
if len > buf.len() {
len = buf.len();
}
if len > 0 {
buf[0..len].copy_from_slice(&self.data.as_ref()[self.offset..self.offset + len]);
self.offset += len;
Ok(len)
} else {
Ok(0)
}
}
}
impl Write for Cursor<&mut Vec<u8>> {
type Err = ();
fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Err> {
if buf.is_empty() {
Ok(0)
} else {
let remaining_len = self.data.len() - self.offset;
let (to_write, to_extend): (_, &[u8]) = {
if remaining_len >= buf.len() {
(buf, &[])
} else {
(&buf[..remaining_len], &buf[remaining_len..])
}
};
self.data[self.offset..self.offset + to_write.len()].copy_from_slice(to_write);
self.data.extend_from_slice(to_extend);
self.offset += buf.len();
Ok(buf.len())
}
}
}
pub fn to_bytes<S: Serial>(x: &S) -> Vec<u8> {
let mut out = Vec::new();
let mut cursor = Cursor::new(&mut out);
x.serial(&mut cursor).expect("Writing to a vector should succeed.");
out
}
pub fn from_bytes<S: Deserial>(source: &[u8]) -> ParseResult<S> {
let mut cursor = Cursor::new(source);
cursor.get()
}