ps_datachunk/serialized/
mod.rs1use std::{ops::Deref, sync::Arc};
2
3use ps_buffer::Buffer;
4use ps_hash::{hash, Hash};
5
6use crate::{utils::HASH_SIZE, DataChunk, EncryptedDataChunk, PsDataChunkError, Result};
7
8#[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
9pub struct SerializedDataChunk {
10 buffer: Buffer,
11 hash: Arc<Hash>,
12}
13
14impl SerializedDataChunk {
15 #[must_use]
16 pub const fn data_length(&self) -> usize {
17 self.buffer.len().saturating_sub(HASH_SIZE)
18 }
19
20 #[must_use]
21 pub const fn is_empty(&self) -> bool {
22 self.buffer.len() <= HASH_SIZE
23 }
24
25 pub fn from_parts<D>(data: D, hash: Arc<Hash>) -> Result<Self>
33 where
34 D: AsRef<[u8]>,
35 {
36 let data = data.as_ref();
37 let buffer_length = HASH_SIZE + data.len();
38
39 let mut buffer = Buffer::with_capacity(buffer_length)?;
40
41 buffer.extend_from_slice(hash.as_bytes())?;
42 buffer.extend_from_slice(data)?;
43
44 let chunk = Self { buffer, hash };
45
46 Ok(chunk)
47 }
48
49 pub fn try_from_parts<D, H>(data: D, hash: H) -> Result<Self>
57 where
58 D: AsRef<[u8]>,
59 H: AsRef<[u8]>,
60 {
61 let data = data.as_ref();
62 let hash = hash.as_ref();
63
64 let hash = Hash::try_from(hash)?.into();
65
66 Self::from_parts(data, hash)
67 }
68
69 pub fn from_data<D>(data: D) -> Result<Self>
71 where
72 D: AsRef<[u8]>,
73 {
74 let data = data.as_ref();
75
76 Self::from_parts(data, hash(data)?.into())
77 }
78
79 #[inline]
81 #[must_use]
82 pub fn serialized_bytes(&self) -> &[u8] {
83 &self.buffer
84 }
85
86 pub fn from_serialized_buffer(buffer: Buffer) -> Result<Self> {
92 if buffer.len() < HASH_SIZE {
93 return Err(PsDataChunkError::InvalidDataChunk);
94 }
95
96 let hash = &buffer[..HASH_SIZE];
97 let data = &buffer[HASH_SIZE..];
98 let calculated_hash = ps_hash::hash(data)?;
99
100 if hash != calculated_hash.as_bytes() {
101 return Err(PsDataChunkError::InvalidHash);
102 }
103
104 let chunk = Self {
105 buffer,
106 hash: Arc::from(calculated_hash),
107 };
108
109 Ok(chunk)
110 }
111
112 #[inline]
113 pub fn into_buffer(self) -> Buffer {
115 self.buffer
116 }
117
118 #[inline]
119 pub fn into_parts(self) -> (Buffer, Arc<Hash>) {
121 (self.buffer, self.hash)
122 }
123}
124
125impl DataChunk for SerializedDataChunk {
126 fn data_ref(&self) -> &[u8] {
127 &self.buffer[HASH_SIZE..]
128 }
129
130 fn encrypt(&self) -> Result<EncryptedDataChunk> {
131 Ok(ps_cypher::encrypt(&self.buffer)?.into())
132 }
133
134 fn hash_ref(&self) -> &Hash {
135 &self.hash
136 }
137
138 fn hash(&self) -> Arc<Hash> {
139 self.hash.clone()
140 }
141
142 fn into_owned(self) -> crate::OwnedDataChunk {
144 let hash = self.hash();
145
146 crate::OwnedDataChunk::from_data_and_hash(self, hash)
147 }
148}
149
150impl AsRef<[u8]> for SerializedDataChunk {
151 fn as_ref(&self) -> &[u8] {
152 self
153 }
154}
155
156impl Deref for SerializedDataChunk {
157 type Target = [u8];
158
159 fn deref(&self) -> &Self::Target {
160 self.data_ref()
161 }
162}