1use core::{
2 borrow::{Borrow, BorrowMut},
3 cmp,
4 ffi::{CStr, c_char},
5 fmt,
6 hash::{Hash, Hasher},
7 ops, slice,
8};
9
10#[derive(Clone, Copy)]
12#[repr(transparent)]
13pub struct SeaArray<const N: usize>(pub [c_char; N]);
14
15impl<const N: usize> fmt::Display for SeaArray<N> {
16 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
17 crate::display_bytes(self.bytes(), f)
18 }
19}
20
21impl<const N: usize> fmt::Debug for SeaArray<N> {
22 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
23 crate::debug_bytes(self.bytes(), f)
24 }
25}
26
27impl<const N: usize> SeaArray<N> {
28 pub const fn new(a: [c_char; N]) -> Self {
29 Self(a)
30 }
31 pub const fn new_ref(a: &[c_char; N]) -> &Self {
32 let ptr = a as *const [c_char; N] as *const Self;
33 unsafe { &*ptr }
34 }
35 pub const fn new_mut(a: &mut [c_char; N]) -> &mut Self {
36 let ptr = a as *mut [c_char; N] as *mut Self;
37 unsafe { &mut *ptr }
38 }
39 pub const fn bytes(&self) -> &[u8] {
41 let bytes = self.all_bytes();
42 match CStr::from_bytes_until_nul(bytes) {
43 Ok(cstr) => cstr.to_bytes(),
44 Err(_) => bytes,
45 }
46 }
47 pub const fn bytes_mut(&mut self) -> &mut [u8] {
49 let ptr = self.all_bytes_mut().as_mut_ptr();
50 let len = self.bytes().len();
51 unsafe { slice::from_raw_parts_mut(ptr, len) }
52 }
53 pub const fn all_bytes(&self) -> &[u8; N] {
55 let ptr = self as *const Self as *const [u8; N];
56 unsafe { &*ptr }
57 }
58 pub const fn all_bytes_mut(&mut self) -> &mut [u8; N] {
60 let ptr = self as *mut Self as *mut [u8; N];
61 unsafe { &mut *ptr }
62 }
63}
64
65impl<const N: usize> PartialEq for SeaArray<N> {
66 fn eq(&self, other: &Self) -> bool {
67 self.bytes() == other.bytes()
68 }
69}
70impl<const N: usize> Eq for SeaArray<N> {}
71impl<const N: usize> Hash for SeaArray<N> {
72 fn hash<H: Hasher>(&self, state: &mut H) {
73 self.bytes().hash(state);
74 }
75}
76impl<const N: usize> Ord for SeaArray<N> {
77 fn cmp(&self, other: &Self) -> cmp::Ordering {
78 self.bytes().cmp(other.bytes())
79 }
80}
81impl<const N: usize> PartialOrd for SeaArray<N> {
82 fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
83 Some(self.cmp(other))
84 }
85}
86impl<const N: usize> AsRef<[u8]> for SeaArray<N> {
87 fn as_ref(&self) -> &[u8] {
88 self.bytes()
89 }
90}
91impl<const N: usize> Borrow<[u8]> for SeaArray<N> {
92 fn borrow(&self) -> &[u8] {
93 self.bytes()
94 }
95}
96impl<const N: usize> AsMut<[u8]> for SeaArray<N> {
97 fn as_mut(&mut self) -> &mut [u8] {
98 self.bytes_mut()
99 }
100}
101impl<const N: usize> BorrowMut<[u8]> for SeaArray<N> {
102 fn borrow_mut(&mut self) -> &mut [u8] {
103 self.bytes_mut()
104 }
105}
106
107impl<const N: usize> ops::Deref for SeaArray<N> {
108 type Target = [u8];
109 fn deref(&self) -> &Self::Target {
110 self.bytes()
111 }
112}
113impl<const N: usize> ops::DerefMut for SeaArray<N> {
114 fn deref_mut(&mut self) -> &mut Self::Target {
115 self.bytes_mut()
116 }
117}
118
119#[cfg(test)]
120mod tests {
121 use super::*;
122 #[test]
123 fn test() {
124 let mut arr = SeaArray([0; 64]);
125 assert_eq!(arr.len(), 0);
126
127 let Some(prefix) = arr.all_bytes_mut().first_chunk_mut() else {
128 unreachable!()
129 };
130 *prefix = *b"hello";
131
132 assert_eq!(&*arr, b"hello");
133 }
134}