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