use crate::v4::error::Result;
use std::cmp::Ordering;
use std::ffi::{CStr, CString};
#[derive(Debug, PartialEq)]
pub struct File([u8; 128]);
impl File {
pub fn new(path: &CStr) -> Result<Self> {
let bytes = path.to_bytes_with_nul();
match bytes.len().cmp(&128) {
Ordering::Less => {
let mut padding = [0u8; 128];
bytes
.iter()
.enumerate()
.for_each(|(i, byte)| padding[i] = *byte);
Ok(Self(padding))
}
Ordering::Equal => Ok(Self(bytes.try_into().unwrap())),
Ordering::Greater => Err("File path does not fit in a 128 byte array"),
}
}
pub fn from_slice_unchecked(path: &[u8]) -> Self {
Self(path.try_into().unwrap())
}
pub fn from_array(name: [u8; 128]) -> Self {
Self(name)
}
pub const EMPTY: Self = Self([0; 128]);
pub fn to_string(&self) -> CString {
CStr::from_bytes_until_nul(&self.0).unwrap().to_owned()
}
pub fn len(&self) -> usize {
128
}
}
impl From<&File> for [u8; 128] {
fn from(file: &File) -> Self {
file.0
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_new_file_below_length() {
let file = File::new(c"12345");
assert!(file.is_ok());
}
#[test]
fn test_new_file_at_length() {
let file = File::new(c"1234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512");
assert!(file.is_ok());
}
#[test]
fn test_new_file_above_length() {
let file = File::new(c"1234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345");
assert!(file.is_err());
}
#[test]
fn test_empty() {
let file = File::EMPTY;
assert_eq!(file.0, [0; 128]);
}
}