rectangle_device_blocks/
raw.rs1use libipld::Ipld;
2use libipld::raw::RawCodec;
3use libipld::pb::{DagPbCodec, PbLink, PbNode};
4use prost::Message;
5use std::iter::{once, Once, Chain, Map, Flatten};
6use std::vec;
7use crate::core::{Block, Cid, DefaultHashType, BLOCK_MAX_BYTES};
8use crate::package::Package;
9use crate::unixfs;
10
11#[derive(Clone)]
12pub struct RawBlockFile {
13 pub block: Block,
14}
15
16impl RawBlockFile {
17 pub fn new(data: &[u8]) -> RawBlockFile {
18 assert!(data.len() <= BLOCK_MAX_BYTES);
19 RawBlockFile { block: Block::encode(RawCodec, DefaultHashType, data).unwrap() }
20 }
21}
22
23impl Package for RawBlockFile {
24 type BlockIterator = Once<Block>;
25
26 fn cid(&self) -> &Cid {
27 &self.block.cid
28 }
29
30 fn total_size(&self) -> u64 {
31 self.block.data.len() as u64
32 }
33
34 fn into_blocks(self) -> Self::BlockIterator {
35 once(self.block)
36 }
37}
38
39#[derive(Clone)]
40pub struct MultiRawBlockFile {
41 pub root: Block,
42 pub parts: Vec<RawBlockFile>,
43}
44
45impl MultiRawBlockFile {
46 pub fn from_bytes(bytes: &[u8]) -> MultiRawBlockFile {
47 let chunks = bytes.chunks(BLOCK_MAX_BYTES);
48 let parts = chunks.map(|chunk| RawBlockFile::new(chunk));
49 MultiRawBlockFile::new(parts.collect())
50 }
51
52 pub fn new(parts: Vec<RawBlockFile>) -> MultiRawBlockFile {
53 let links: Vec<PbLink> = parts.iter().map(|part| part.link("".to_string())).collect();
54 let sizes: Vec<u64> = parts.iter().map(|part| part.block.data.len() as u64).collect();
55 let filesize = sizes.iter().sum();
56
57 let file = unixfs::pb::Data {
58 r#type: unixfs::pb::data::DataType::File.into(),
59 blocksizes: sizes,
60 filesize: Some(filesize),
61 data: None,
62 hash_type: None,
63 fanout: None
64 };
65
66 let node = {
67 let mut data: Vec<u8> = vec![];
68 file.encode(&mut data).unwrap();
69 PbNode { links, data: data.into_boxed_slice() }
70 };
71 let ipld: Ipld = node.into();
72
73 let root = Block::encode(DagPbCodec, DefaultHashType, &ipld).unwrap();
76 assert!(root.data.len() <= BLOCK_MAX_BYTES);
77
78 MultiRawBlockFile { root, parts }
79 }
80}
81
82type RawIntoBlocksFn = fn(RawBlockFile) -> <RawBlockFile as Package>::BlockIterator;
83
84impl Package for MultiRawBlockFile {
85 type BlockIterator = Chain<Once<Block>, Flatten<Map< vec::IntoIter<RawBlockFile>, RawIntoBlocksFn >>>;
86
87 fn cid(&self) -> &Cid {
88 &self.root.cid
89 }
90
91 fn total_size(&self) -> u64 {
92 let parts_size: u64 = self.parts.iter().map(|part| part.total_size()).sum();
93 let root_size = self.root.data.len() as u64;
94 parts_size + root_size
95 }
96
97 fn into_blocks(self) -> Self::BlockIterator {
98 once(self.root).chain(self.parts.into_iter().map(RawBlockFile::into_blocks as RawIntoBlocksFn).flatten())
99 }
100}