oasis_core_runtime/storage/mkvs/
marshal.rs

1use std::io::Cursor;
2
3use anyhow::{anyhow, Result};
4use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
5
6/// The `Marshal` trait is used for marshaling and unmarshaling MKVS trees.
7pub trait Marshal {
8    /// Marshal the object into a binary form and return it as a new vector.
9    fn marshal_binary(&self) -> Result<Vec<u8>>;
10    /// Unmarshal from the given byte slice reference and modify `self`.
11    fn unmarshal_binary(&mut self, data: &[u8]) -> Result<usize>;
12}
13
14impl Marshal for u16 {
15    fn marshal_binary(&self) -> Result<Vec<u8>> {
16        let mut result: Vec<u8> = Vec::with_capacity(2);
17        result.write_u16::<LittleEndian>(*self)?;
18        Ok(result)
19    }
20
21    fn unmarshal_binary(&mut self, data: &[u8]) -> Result<usize> {
22        if data.len() < 2 {
23            Err(anyhow!("mkvs: malformed 16-bit integer"))
24        } else {
25            let mut reader = Cursor::new(data);
26            *self = reader.read_u16::<LittleEndian>()?;
27            Ok(2)
28        }
29    }
30}
31
32impl Marshal for u32 {
33    fn marshal_binary(&self) -> Result<Vec<u8>> {
34        let mut result: Vec<u8> = Vec::with_capacity(4);
35        result.write_u32::<LittleEndian>(*self)?;
36        Ok(result)
37    }
38
39    fn unmarshal_binary(&mut self, data: &[u8]) -> Result<usize> {
40        if data.len() < 4 {
41            Err(anyhow!("mkvs: malformed 32-bit integer"))
42        } else {
43            let mut reader = Cursor::new(data);
44            *self = reader.read_u32::<LittleEndian>()?;
45            Ok(4)
46        }
47    }
48}
49
50impl Marshal for u64 {
51    fn marshal_binary(&self) -> Result<Vec<u8>> {
52        let mut result: Vec<u8> = Vec::with_capacity(8);
53        result.write_u64::<LittleEndian>(*self)?;
54        Ok(result)
55    }
56
57    fn unmarshal_binary(&mut self, data: &[u8]) -> Result<usize> {
58        if data.len() < 8 {
59            Err(anyhow!("mkvs: malformed 64-bit integer"))
60        } else {
61            let mut reader = Cursor::new(data);
62            *self = reader.read_u64::<LittleEndian>()?;
63            Ok(8)
64        }
65    }
66}