1#![no_std]
2extern crate alloc;
3pub use crate::generated::ckbfs::{Bytes, CKBFSData};
4use alloc::{string::String, vec::Vec};
5
6use generated::ckbfs::{BackLink, BackLinkVec, Byte32, Indexes, Uint32};
7use molecule::prelude::{Builder, Entity};
8
9pub mod generated;
10
11impl Into<Bytes> for &[u8] {
12 fn into(self) -> Bytes {
13 let len = self.len();
14 let mut vec: Vec<u8> = Vec::with_capacity(4 + len);
15 vec.extend_from_slice(&(len as u32).to_le_bytes()[..]);
16 vec.extend_from_slice(self);
17 Bytes::new_unchecked(Bytes::from_slice(vec.as_slice()).unwrap().as_bytes())
18 }
19}
20
21#[derive(Debug, Clone)]
22pub struct BackLinkNative {
23 pub indexes: Vec<u32>,
24 pub checksum: u32,
25 pub tx_hash: [u8; 32],
26}
27
28impl Into<Indexes> for Vec<u32> {
29 fn into(self) -> Indexes {
30 Indexes::new_builder()
31 .extend(self.iter().map(|x| {
32 Uint32::new_unchecked(molecule::bytes::Bytes::from(x.to_le_bytes().to_vec()))
33 }))
34 .build()
35 }
36}
37
38impl Into<BackLinkNative> for BackLink {
39 fn into(self) -> BackLinkNative {
40 let indexes = self
41 .indexes()
42 .into_iter()
43 .map(|x| {
44 u32::from_le_bytes(x.as_slice().try_into().unwrap())
45 .try_into()
46 .unwrap()
47 })
48 .collect::<Vec<u32>>();
49 let checksum = u32::from_le_bytes(self.checksum().as_slice().try_into().unwrap());
50 let tx_hash = self.tx_hash().as_slice().try_into().unwrap();
51 BackLinkNative {
52 indexes,
53 checksum,
54 tx_hash,
55 }
56 }
57}
58
59impl Into<BackLink> for BackLinkNative {
60 fn into(self) -> BackLink {
61 BackLink::new_builder()
62 .indexes(
63 Indexes::new_builder()
64 .extend(self.indexes.iter().map(|x| {
65 Uint32::new_unchecked(molecule::bytes::Bytes::from(
66 x.to_le_bytes().to_vec(),
67 ))
68 }))
69 .build(),
70 )
71 .checksum(Uint32::new_unchecked(molecule::bytes::Bytes::from(
72 self.checksum.to_le_bytes().to_vec(),
73 )))
74 .tx_hash(Byte32::new_unchecked(molecule::bytes::Bytes::from(
75 self.tx_hash.to_vec(),
76 )))
77 .build()
78 }
79}
80
81#[derive(Debug, Clone)]
82pub struct CKBFSDataNative {
83 pub indexes: Vec<u32>,
84 pub checksum: u32,
85 pub content_type: String,
86 pub filename: String,
87 pub backlinks: Vec<BackLinkNative>,
88}
89
90impl From<CKBFSDataNative> for CKBFSData {
91 fn from(data: CKBFSDataNative) -> Self {
92 let content_type = data.content_type.as_bytes().into();
93 let filename = data.filename.as_bytes().into();
94 let indexes = data
95 .indexes
96 .iter()
97 .map(|x| Uint32::new_unchecked(molecule::bytes::Bytes::from(x.to_le_bytes().to_vec())))
98 .collect::<_>();
99 let backlinks = data
100 .backlinks
101 .into_iter()
102 .map(|backlink| backlink.into())
103 .collect::<Vec<BackLink>>();
104 CKBFSData::new_builder()
105 .indexes(Indexes::new_builder().set(indexes).build())
106 .checksum(Uint32::new_unchecked(molecule::bytes::Bytes::from(
107 data.checksum.to_le_bytes().to_vec(),
108 )))
109 .filename(filename)
110 .content_type(content_type)
111 .backlinks(BackLinkVec::new_builder().extend(backlinks).build())
112 .build()
113 }
114}
115
116impl Into<CKBFSDataNative> for CKBFSData {
117 fn into(self) -> CKBFSDataNative {
118 let content_type = String::from_utf8(self.content_type().as_slice().to_vec())
119 .expect("Failed to extract content-type");
120 let filename = String::from_utf8(self.filename().as_slice().to_vec())
121 .expect("Failed to extract filname");
122 let indexes = self
123 .indexes()
124 .into_iter()
125 .map(|x| u32::from_le_bytes(x.as_slice().try_into().unwrap()))
126 .collect::<Vec<u32>>();
127 let checksum = u32::from_le_bytes(self.checksum().as_slice().try_into().unwrap());
128 let backlinks = self
129 .backlinks()
130 .into_iter()
131 .map(|raw_backlink| raw_backlink.into())
132 .collect::<Vec<BackLinkNative>>();
133 CKBFSDataNative {
134 indexes,
135 checksum,
136 content_type,
137 filename,
138 backlinks,
139 }
140 }
141}