shadow_crypt_core/
version.rs1use crate::errors::HeaderError;
2
3pub const MAGIC: [u8; 6] = *b"SHADOW";
5
6pub const PREAMBLE_LENGTH: usize = MAGIC.len() + 1;
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10pub enum Version {
11 V1,
12 V2,
13 V3,
14}
15
16impl Version {
17 pub fn as_str(&self) -> &'static str {
18 match self {
19 Version::V1 => "v1",
20 Version::V2 => "v2",
21 Version::V3 => "v3",
22 }
23 }
24
25 pub fn as_u8(&self) -> u8 {
26 match self {
27 Version::V1 => 1,
28 Version::V2 => 2,
29 Version::V3 => 3,
30 }
31 }
32}
33
34impl TryFrom<u8> for Version {
35 type Error = ();
36
37 fn try_from(value: u8) -> Result<Self, Self::Error> {
38 match value {
39 1 => Ok(Version::V1),
40 2 => Ok(Version::V2),
41 3 => Ok(Version::V3),
42 _ => Err(()),
43 }
44 }
45}
46
47pub fn read_file_version(bytes: &[u8]) -> Result<Version, HeaderError> {
53 if bytes.len() < PREAMBLE_LENGTH {
54 return Err(HeaderError::InsufficientBytes);
55 }
56 if bytes[..MAGIC.len()] != MAGIC {
57 return Err(HeaderError::InvalidData);
58 }
59 Version::try_from(bytes[MAGIC.len()]).map_err(|_| HeaderError::InvalidData)
60}
61
62#[cfg(test)]
63mod tests {
64 use super::*;
65
66 #[test]
67 fn test_version_as_str() {
68 assert_eq!(Version::V1.as_str(), "v1");
69 assert_eq!(Version::V2.as_str(), "v2");
70 assert_eq!(Version::V3.as_str(), "v3");
71 }
72
73 #[test]
74 fn test_version_as_u8() {
75 assert_eq!(Version::V1.as_u8(), 1);
76 assert_eq!(Version::V2.as_u8(), 2);
77 assert_eq!(Version::V3.as_u8(), 3);
78 }
79
80 #[test]
81 fn test_try_from_u8() {
82 assert_eq!(Version::try_from(1), Ok(Version::V1));
83 assert_eq!(Version::try_from(2), Ok(Version::V2));
84 assert_eq!(Version::try_from(3), Ok(Version::V3));
85 assert!(Version::try_from(0).is_err());
86 assert!(Version::try_from(4).is_err());
87 }
88
89 #[test]
90 fn test_read_file_version() {
91 let mut bytes = b"SHADOW".to_vec();
92 bytes.push(2);
93 assert_eq!(read_file_version(&bytes).unwrap(), Version::V2);
94
95 bytes[6] = 1;
96 assert_eq!(read_file_version(&bytes).unwrap(), Version::V1);
97
98 bytes[6] = 99;
99 assert!(read_file_version(&bytes).is_err());
100
101 assert!(read_file_version(b"SHADO").is_err());
102 assert!(read_file_version(b"NOTSHD\x01").is_err());
103 }
104}