1use nuts_backend::{Backend, Binary, Create, IdSize, Open, ReceiveHeader, HEADER_MAX_SIZE};
34use nuts_bytes::{FromBytes, ToBytes};
35use serde::{Deserialize, Deserializer, Serialize, Serializer};
36use std::borrow::Cow;
37use std::collections::HashMap;
38use std::convert::TryInto;
39use std::num::ParseIntError;
40use std::str::FromStr;
41use std::{cmp, fmt, mem};
42use thiserror::Error;
43
44pub fn deserialize_header<'de, D: Deserializer<'de>>(
45 deserializer: D,
46) -> Result<Option<[u8; HEADER_MAX_SIZE]>, D::Error> {
47 let value: Option<Vec<u8>> = Deserialize::deserialize(deserializer)?;
48
49 match value {
50 Some(vec) => match vec.try_into() {
51 Ok(buf) => Ok(Some(buf)),
52 Err(_) => Err(serde::de::Error::custom("header has an invalid size")),
53 },
54 None => Ok(None),
55 }
56}
57
58pub fn serialize_header<S: Serializer>(
59 value: &Option<[u8; HEADER_MAX_SIZE]>,
60 serializer: S,
61) -> Result<S::Ok, S::Error> {
62 Serialize::serialize(&value.map(|buf| buf.to_vec()), serializer)
63}
64
65#[derive(Debug, Error)]
67pub enum Error {
68 #[error("no such id: {0}")]
70 NoSuchId(Id),
71
72 #[error("already aquired: {0}")]
74 AlreadAquired(Id),
75
76 #[error("no header data available")]
78 NoHeader,
79
80 #[error(transparent)]
82 Bytes(#[from] nuts_bytes::Error),
83}
84
85#[derive(Clone, Copy, Debug, FromBytes, PartialEq, ToBytes)]
87pub struct Id(u32);
88
89impl Binary for Id {
90 fn from_bytes(bytes: &[u8]) -> Option<Self> {
91 match bytes.try_into() {
92 Ok(buf) => Some(Id(u32::from_be_bytes(buf))),
93 Err(_) => None,
94 }
95 }
96
97 fn as_bytes(&self) -> Vec<u8> {
98 self.0.to_be_bytes().to_vec()
99 }
100}
101
102impl IdSize for Id {
103 fn size() -> usize {
104 mem::size_of::<u32>()
105 }
106}
107
108impl fmt::Display for Id {
109 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
110 fmt::Display::fmt(&self.0, fmt)
111 }
112}
113
114impl FromStr for Id {
115 type Err = ParseIntError;
116
117 fn from_str(s: &str) -> Result<Self, ParseIntError> {
118 FromStr::from_str(s).map(Id)
119 }
120}
121
122#[derive(Clone, Debug, PartialEq)]
123pub struct Settings;
124
125impl Binary for Settings {
126 fn from_bytes(bytes: &[u8]) -> Option<Settings> {
127 if bytes.is_empty() {
128 Some(Settings)
129 } else {
130 None
131 }
132 }
133
134 fn as_bytes(&self) -> Vec<u8> {
135 vec![]
136 }
137}
138
139#[derive(Debug, Deserialize, PartialEq, Serialize)]
143pub struct MemoryBackend {
144 bsize: u32,
145 blocks: HashMap<u32, Vec<u8>>,
146 #[serde(
147 deserialize_with = "deserialize_header",
148 serialize_with = "serialize_header"
149 )]
150 header: Option<[u8; HEADER_MAX_SIZE]>,
151}
152
153impl MemoryBackend {
154 pub fn new() -> MemoryBackend {
158 Self::new_with_bsize(512)
159 }
160
161 pub fn new_with_bsize(bsize: u32) -> MemoryBackend {
164 MemoryBackend {
165 bsize,
166 blocks: HashMap::new(),
167 header: None,
168 }
169 }
170
171 pub fn block_size(&self) -> u32 {
173 self.bsize
174 }
175
176 pub fn get(&self, id: &Id) -> Option<&[u8]> {
180 self.blocks.get(&id.0).map(|buf| buf.as_slice())
181 }
182
183 pub fn insert(&mut self) -> Result<Id, Error> {
189 self.insert_data(&[])
190 }
191
192 pub fn insert_data(&mut self, data: &[u8]) -> Result<Id, Error> {
200 let id = Id(self.max_id() + 1);
201 let mut block = vec![0; self.bsize as usize];
202
203 let n = cmp::min(block.len(), data.len());
204 block[..n].copy_from_slice(&data[..n]);
205
206 match self.blocks.insert(id.0, block) {
207 Some(_) => Err(Error::AlreadAquired(id)),
208 None => Ok(id),
209 }
210 }
211
212 fn max_id(&self) -> u32 {
213 *self.blocks.keys().max().unwrap_or(&0)
214 }
215}
216
217impl Default for MemoryBackend {
218 fn default() -> Self {
219 Self::new()
220 }
221}
222
223impl ReceiveHeader<Self> for MemoryBackend {
224 fn get_header_bytes(&mut self, bytes: &mut [u8; HEADER_MAX_SIZE]) -> Result<(), Error> {
225 match self.header.as_ref() {
226 Some(source) => {
227 bytes.copy_from_slice(source);
228 Ok(())
229 }
230 None => Err(Error::NoHeader),
231 }
232 }
233}
234
235impl Create<Self> for MemoryBackend {
236 fn settings(&self) -> Settings {
237 Settings
238 }
239
240 fn build(
241 mut self,
242 header: [u8; HEADER_MAX_SIZE],
243 _overwrite: bool,
244 ) -> Result<MemoryBackend, Error> {
245 <Self as Backend>::write_header(&mut self, &header)?;
246 Ok(self)
247 }
248}
249
250impl Open<Self> for MemoryBackend {
251 fn build(self, _settings: Settings) -> Result<MemoryBackend, Error> {
252 Ok(self)
253 }
254}
255
256impl Backend for MemoryBackend {
257 type Settings = Settings;
258 type Err = Error;
259 type Id = Id;
260 type Info = ();
261
262 fn info(&self) -> Result<(), Error> {
263 Ok(())
264 }
265
266 fn block_size(&self) -> u32 {
267 self.bsize
268 }
269
270 fn aquire(&mut self, buf: &[u8]) -> Result<Id, Error> {
271 self.insert_data(buf)
272 }
273
274 fn release(&mut self, id: Id) -> Result<(), Error> {
275 self.blocks.remove(&id.0);
276 Ok(())
277 }
278
279 fn read(&mut self, id: &Id, buf: &mut [u8]) -> Result<usize, Error> {
280 match self.blocks.get(&id.0) {
281 Some(src) => {
282 let len = cmp::min(src.len(), buf.len());
283
284 let source = &src[..len];
285 let target = &mut buf[..len];
286
287 target.copy_from_slice(source);
288
289 Ok(len)
290 }
291 None => Err(Error::NoSuchId(*id)),
292 }
293 }
294
295 fn write(&mut self, id: &Id, buf: &[u8]) -> Result<usize, Error> {
296 match self.blocks.get_mut(&id.0) {
297 Some(target) => {
298 let mut source = Cow::from(buf);
299 let mut len = source.len();
300
301 if len != self.bsize as usize {
302 len = cmp::min(source.len(), self.bsize as usize);
303 source.to_mut().resize(self.bsize as usize, 0);
304 }
305
306 target.copy_from_slice(&source);
307
308 Ok(len)
309 }
310 None => Err(Error::NoSuchId(*id)),
311 }
312 }
313
314 fn write_header(&mut self, buf: &[u8; HEADER_MAX_SIZE]) -> Result<(), Error> {
315 self.header = Some(*buf);
316 Ok(())
317 }
318
319 fn delete(self) {
320 }
322}