toe_beans/v4/message/
file.rs1use crate::v4::error::Result;
2use std::cmp::Ordering;
3use std::ffi::{CStr, CString};
4
5#[derive(Debug, PartialEq)]
15pub struct File([u8; 128]);
16
17impl File {
18 pub fn new(path: &CStr) -> Result<Self> {
22 let bytes = path.to_bytes_with_nul();
23 match bytes.len().cmp(&128) {
24 Ordering::Less => {
25 let mut padding = [0u8; 128];
26 bytes
27 .iter()
28 .enumerate()
29 .for_each(|(i, byte)| padding[i] = *byte);
30 Ok(Self(padding))
31 }
32 Ordering::Equal => Ok(Self(bytes.try_into().unwrap())),
33 Ordering::Greater => Err("File path does not fit in a 128 byte array"),
34 }
35 }
36
37 pub fn from_slice_unchecked(path: &[u8]) -> Self {
44 Self(path.try_into().unwrap())
45 }
46
47 pub const EMPTY: Self = Self([0; 128]);
51
52 pub fn to_string(&self) -> CString {
55 CStr::from_bytes_until_nul(&self.0).unwrap().to_owned()
56 }
57
58 pub fn len(&self) -> usize {
64 128
65 }
66}
67
68impl From<&File> for [u8; 128] {
69 fn from(file: &File) -> Self {
70 file.0
71 }
72}
73
74#[cfg(test)]
75mod tests {
76 use super::*;
77
78 #[test]
79 fn test_new_file_below_length() {
80 let file = File::new(c"12345");
81 assert!(file.is_ok());
82 }
83
84 #[test]
85 fn test_new_file_at_length() {
86 let file = File::new(c"1234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512");
88 assert!(file.is_ok());
89 }
90
91 #[test]
92 fn test_new_file_above_length() {
93 let file = File::new(c"1234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345");
94 assert!(file.is_err());
95 }
96
97 #[test]
98 fn test_empty() {
99 let file = File::EMPTY;
100 assert_eq!(file.0, [0; 128]);
101 }
102}