hadris_common/types/
file.rs1use core::{fmt, ops::Range};
2
3#[derive(Clone, Copy, PartialEq, Eq)]
5pub struct FixedFilename<const N: usize> {
6 pub data: [u8; N],
7 pub len: usize,
8}
9
10impl<const N: usize> FixedFilename<N> {
11 pub const fn empty() -> Self {
12 Self {
13 data: [0; N],
14 len: 0,
15 }
16 }
17
18 pub const fn with_size(size: usize) -> Self {
19 Self {
20 data: [0; N],
21 len: size,
22 }
23 }
24
25 pub fn as_str(&self) -> &str {
26 unsafe { core::str::from_utf8_unchecked(self.as_bytes()) }
27 }
28
29 pub fn allocate(&mut self, bytes: usize) {
30 let len = self.len;
31 assert!(bytes + len < N);
32 self.len += bytes;
33 }
35
36 pub fn as_bytes(&self) -> &[u8] {
37 &self.data[0..self.len]
38 }
39
40 pub fn as_bytes_mut(&mut self) -> &mut [u8] {
41 &mut self.data[0..self.len]
42 }
43
44 pub fn truncate(&mut self, new_size: usize) {
45 assert!(new_size <= N);
46 self.len = new_size;
47 }
48
49 pub fn len(&self) -> usize {
50 self.len
51 }
52
53 pub fn push_slice(&mut self, slice: &[u8]) -> Range<usize> {
54 assert!(self.len + slice.len() <= self.data.len());
55 let start = self.len;
56 self.len += slice.len();
57 self.data[start..self.len].copy_from_slice(slice);
58 start..self.len
59 }
60
61 pub fn push_byte(&mut self, b: u8) -> usize {
62 self.data[self.len] = b;
63 self.len += 1;
64 self.len - 1
65 }
66}
67
68impl<const N: usize> fmt::Debug for FixedFilename<N> {
69 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
70 f.debug_tuple("FixedFilename")
71 .field(&self.as_str())
72 .finish()
73 }
74}
75
76impl<const N: usize> From<&[u8]> for FixedFilename<N> {
77 fn from(value: &[u8]) -> Self {
78 assert!(value.len() <= N);
79 let mut str = FixedFilename::with_size(value.len());
80 str.data[0..value.len()].copy_from_slice(value);
81 return str;
82 }
83}