1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
use crate::header_v0::HeaderV0;
use std::convert::TryFrom;
use pad::PadStr;
#[derive(Clone, Hash, Debug, Eq, Ord, PartialOrd, PartialEq)]
pub struct HeaderBinaryV0 {
pub version: [u8; 2],
pub datatype: [u8; 1],
pub name: [u8; 128],
pub created: [u8; 8],
pub edited: [u8; 8],
pub file_name: [u8; 128],
pub buffer_size: [u8; 8],
}
#[derive(Clone, Hash, Debug, Eq, Ord, PartialOrd, PartialEq)]
pub enum DataType {
Password = 0,
File = 1,
}
impl HeaderBinaryV0 {
#[must_use] pub fn to_bytes(&self) -> Vec<u8> {
let mut output = Vec::new();
output.extend_from_slice(&self.version);
output.extend_from_slice(&self.datatype);
output.extend_from_slice(&self.name);
output.extend_from_slice(&self.created);
output.extend_from_slice(&self.edited);
output.extend_from_slice(&self.file_name);
output.extend_from_slice(&self.buffer_size);
output.resize(1024, 0);
output
}
#[must_use] pub fn from_bytes(bytes: &[u8; 1024]) -> Self {
let version_and_rest = bytes.split_at(2);
let datatype_and_rest = version_and_rest.1.split_at(1);
let name_and_rest = datatype_and_rest.1.split_at(128);
let created_and_rest = name_and_rest.1.split_at(8);
let edited_and_rest = created_and_rest.1.split_at(8);
let file_name_and_rest = edited_and_rest.1.split_at(128);
let buffer_size_and_rest = file_name_and_rest.1.split_at(8);
Self {
version: <[u8; 2]>::try_from(version_and_rest.0).unwrap(),
datatype: <[u8; 1]>::try_from(datatype_and_rest.0).unwrap(),
name: <[u8; 128]>::try_from(name_and_rest.0).unwrap(),
created: <[u8; 8]>::try_from(created_and_rest.0).unwrap(),
edited: <[u8; 8]>::try_from(edited_and_rest.0).unwrap(),
file_name: <[u8; 128]>::try_from(file_name_and_rest.0).unwrap(),
buffer_size: <[u8; 8]>::try_from(buffer_size_and_rest.0).unwrap(),
}
}
#[must_use] pub fn from_parameters(datatype: &DataType, name: &str, old_create_date: Option<i64>, file_name: &str, buffer_size: u64) -> Self {
let mut create_date = chrono::Local::now().timestamp();
if let Some(create) = old_create_date {
create_date = create;
}
let datatype_id: u8;
match datatype {
DataType::Password => { datatype_id = 0 }
DataType::File => { datatype_id = 1 }
}
let name_padded = name.pad_to_width(128);
let file_name_padded = file_name.pad_to_width(128);
Self {
version: 0_u16.to_be_bytes(),
datatype: datatype_id.to_be_bytes(),
name: <[u8; 128]>::try_from(name_padded.as_bytes()).unwrap(),
created: create_date.to_be_bytes(),
edited: chrono::Local::now().timestamp().to_be_bytes(),
file_name: <[u8; 128]>::try_from(file_name_padded.as_bytes()).unwrap(),
buffer_size: buffer_size.to_be_bytes(),
}
}
#[must_use] pub fn from_header(header: &HeaderV0) -> Self {
Self {
version: header.version.to_be_bytes(),
datatype: header.datatype.to_be_bytes(),
name: <[u8; 128]>::try_from(header.name.as_bytes()).unwrap(),
created: header.created.to_be_bytes(),
edited: header.edited.to_be_bytes(),
file_name: <[u8; 128]>::try_from(header.file_name.as_bytes()).unwrap(),
buffer_size: header.buffer_size.to_be_bytes(),
}
}
}