1use core::cmp::{Ordering, PartialEq, Eq, PartialOrd, Ord};
2use core::fmt::{self, Debug};
3use core::borrow::Borrow;
4use core::num::NonZero;
5use core::ops::Deref;
6use core::hash::Hash;
7
8use crate::Comrade;
9
10#[derive(Clone)]
11enum OurInner<T, const N: usize> {
12 Inline { len: core::num::NonZero<u8>, content: [u8; N] },
13 Outline { content: T },
14}
15
16#[derive(Clone)]
25pub struct OurBytes<T: Comrade, const N: usize>(OurInner<T, N>);
26
27impl<T: Comrade, const N: usize> OurBytes<T, N> {
28 pub const fn new() -> Self {
30 Self(OurInner::Inline { len: NonZero::<u8>::MAX, content: [0; N] })
31 }
32 pub fn convert<const M: usize>(self) -> OurBytes<T, M> {
39 match self.0 {
40 OurInner::Inline { .. } => OurBytes::from(self.as_slice()),
41 OurInner::Outline { content } => OurBytes::from(content),
42 }
43 }
44 pub fn as_slice(&self) -> &[u8] {
46 self
47 }
48}
49
50impl<T: Comrade, const N: usize> Deref for OurBytes<T, N> {
51 type Target = [u8];
52 fn deref(&self) -> &Self::Target {
53 match &self.0 {
54 OurInner::Inline { len, content } => &content[..(!len.get()) as usize],
55 OurInner::Outline { content } => content.as_slice(),
56 }
57 }
58}
59
60impl<T: Comrade, const N: usize> From<&[u8]> for OurBytes<T, N> {
61 fn from(value: &[u8]) -> Self {
62 if value.len() <= N && value.len() < u8::MAX as usize {
63 let mut content = [0; N];
64 content[..value.len()].copy_from_slice(value);
65 Self(OurInner::Inline { len: NonZero::new(!(value.len() as u8)).unwrap(), content })
66 } else {
67 Self(OurInner::Outline { content: T::from_slice(value) })
68 }
69 }
70}
71
72impl<T: Comrade, const N: usize> From<T> for OurBytes<T, N> {
73 fn from(content: T) -> Self {
74 Self(OurInner::Outline { content })
75 }
76}
77
78impl<T: Comrade, const N: usize> Default for OurBytes<T, N> {
79 fn default() -> Self {
80 Self::new()
81 }
82}
83
84impl<T: Comrade, const N: usize> AsRef<[u8]> for OurBytes<T, N> {
85 fn as_ref(&self) -> &[u8] {
86 self
87 }
88}
89
90impl<T: Comrade, const N: usize> Borrow<[u8]> for OurBytes<T, N> {
91 fn borrow(&self) -> &[u8] {
92 self
93 }
94}
95
96impl<T: Comrade, const N: usize> Debug for OurBytes<T, N> {
97 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
98 <[u8] as Debug>::fmt(&**self, f)
99 }
100}
101
102impl<T: Comrade, const N: usize> Hash for OurBytes<T, N> {
103 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
104 (**self).hash(state)
105 }
106}
107
108impl<U: Deref<Target = [u8]>, T: Comrade, const N: usize> PartialEq<U> for OurBytes<T, N> {
109 fn eq(&self, other: &U) -> bool {
110 (**self).eq(&**other)
111 }
112}
113
114impl<T: Comrade, const N: usize> PartialEq<OurBytes<T, N>> for &[u8] {
115 fn eq(&self, other: &OurBytes<T, N>) -> bool {
116 (**self).eq(&**other)
117 }
118}
119
120impl<T: Comrade, const N: usize> Eq for OurBytes<T, N> {}
121
122impl<U: Deref<Target = [u8]>, T: Comrade, const N: usize> PartialOrd<U> for OurBytes<T, N> {
123 fn partial_cmp(&self, other: &U) -> Option<Ordering> {
124 (**self).partial_cmp(&**other)
125 }
126}
127
128impl<T: Comrade, const N: usize> PartialOrd<OurBytes<T, N>> for &[u8] {
129 fn partial_cmp(&self, other: &OurBytes<T, N>) -> Option<Ordering> {
130 (**self).partial_cmp(&**other)
131 }
132}
133
134impl<T: Comrade, const N: usize> Ord for OurBytes<T, N> {
135 fn cmp(&self, other: &Self) -> Ordering {
136 (**self).cmp(&**other)
137 }
138}