1use anyhow::{Result, anyhow};
5use byteorder::ReadBytesExt;
6use integer_encoding::{VarInt, VarIntReader};
7use num_enum::{IntoPrimitive, TryFromPrimitive};
8use serde::Serialize;
9use serde::de::DeserializeOwned;
10use std::io::{Read, Write};
11use std::marker::PhantomData;
12
13pub const MAX_VARINT_LENGTH: usize = 10;
14pub const BLOB_ENCODING_BYTES: usize = 1;
15
16#[derive(Copy, Clone, Debug, Eq, PartialEq, TryFromPrimitive, IntoPrimitive)]
17#[repr(u8)]
18pub enum BlobEncoding {
19 Bcs = 1,
20}
21
22pub struct Blob {
23 pub data: Vec<u8>,
24 pub encoding: BlobEncoding,
25}
26
27impl Blob {
28 pub fn encode<T: Serialize>(value: &T, encoding: BlobEncoding) -> Result<Self> {
29 let value_buf = bcs::to_bytes(value)?;
30 let (data, encoding) = match encoding {
31 BlobEncoding::Bcs => (value_buf, encoding),
32 };
33 Ok(Blob { data, encoding })
34 }
35 pub fn decode<T: DeserializeOwned>(self) -> Result<T> {
36 let data = match &self.encoding {
37 BlobEncoding::Bcs => self.data,
38 };
39 let res = bcs::from_bytes(&data)?;
40 Ok(res)
41 }
42 pub fn read<R: Read>(rbuf: &mut R) -> Result<Blob> {
43 let len = rbuf.read_varint::<u64>()? as usize;
44 if len == 0 {
45 return Err(anyhow!("Invalid object length of 0 in file"));
46 }
47 let encoding = rbuf.read_u8()?;
48 let mut data = vec![0u8; len];
49 rbuf.read_exact(&mut data)?;
50 let blob = Blob {
51 data,
52 encoding: BlobEncoding::try_from(encoding)?,
53 };
54 Ok(blob)
55 }
56 pub fn write<W: Write>(&self, wbuf: &mut W) -> Result<usize> {
57 let mut buf = [0u8; MAX_VARINT_LENGTH];
58 let mut counter = 0;
59 let n = (self.data.len() as u64).encode_var(&mut buf);
60 wbuf.write_all(&buf[0..n])?;
61 counter += n;
62 buf[0] = self.encoding.into();
63 wbuf.write_all(&buf[0..BLOB_ENCODING_BYTES])?;
64 counter += 1;
65 wbuf.write_all(&self.data)?;
66 counter += self.data.len();
67 Ok(counter)
68 }
69 pub fn size(&self) -> usize {
70 let mut blob_size = self.data.len().required_space();
71 blob_size += BLOB_ENCODING_BYTES;
72 blob_size += self.data.len();
73 blob_size
74 }
75 pub fn to_bytes(&self) -> Vec<u8> {
76 [vec![self.encoding.into()], self.data.clone()].concat()
77 }
78 pub fn from_bytes<T: DeserializeOwned>(bytes: &[u8]) -> Result<T> {
79 let (encoding, data) = bytes.split_first().ok_or(anyhow!("empty bytes"))?;
80 Blob {
81 data: data.to_vec(),
82 encoding: BlobEncoding::try_from(*encoding)?,
83 }
84 .decode()
85 }
86}
87
88pub struct BlobIter<T> {
90 reader: Box<dyn Read>,
91 _phantom: PhantomData<T>,
92}
93
94impl<T: DeserializeOwned> BlobIter<T> {
95 pub fn new(reader: Box<dyn Read>) -> Self {
96 Self {
97 reader,
98 _phantom: PhantomData,
99 }
100 }
101 fn next_blob(&mut self) -> Result<T> {
102 let blob = Blob::read(&mut self.reader)?;
103 blob.decode()
104 }
105}
106
107impl<T: DeserializeOwned> Iterator for BlobIter<T> {
108 type Item = T;
109 fn next(&mut self) -> Option<Self::Item> {
110 self.next_blob().ok()
111 }
112}