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 fn from_array(name: [u8; 128]) -> Self {
49 Self(name)
50 }
51
52 pub const EMPTY: Self = Self([0; 128]);
56
57 pub fn to_string(&self) -> CString {
60 CStr::from_bytes_until_nul(&self.0).unwrap().to_owned()
61 }
62
63 pub fn len(&self) -> usize {
69 128
70 }
71}
72
73impl From<&File> for [u8; 128] {
74 fn from(file: &File) -> Self {
75 file.0
76 }
77}
78
79#[cfg(test)]
80mod tests {
81 use super::*;
82
83 #[test]
84 fn test_new_file_below_length() {
85 let file = File::new(c"12345");
86 assert!(file.is_ok());
87 }
88
89 #[test]
90 fn test_new_file_at_length() {
91 let file = File::new(c"1234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512");
93 assert!(file.is_ok());
94 }
95
96 #[test]
97 fn test_new_file_above_length() {
98 let file = File::new(c"1234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345");
99 assert!(file.is_err());
100 }
101
102 #[test]
103 fn test_empty() {
104 let file = File::EMPTY;
105 assert_eq!(file.0, [0; 128]);
106 }
107}