1use std::mem::MaybeUninit;
2use std::{ ptr, str, slice, fmt };
3use std::ops::Deref;
4
5pub const MAX_LEN: usize = 30;
6
7#[derive(Clone, Copy)]
8pub struct Short {
9 len: u8,
10 value: [MaybeUninit<u8>; MAX_LEN],
11}
12
13impl Short {
16 #[inline(always)]
25 pub unsafe fn from_slice(slice: &str) -> Self {
26 let mut short = Short {
27 value: MaybeUninit::uninit().assume_init(),
28 len: slice.len() as u8,
29 };
30
31 ptr::copy_nonoverlapping(slice.as_ptr(), short.value.as_mut_ptr() as _, slice.len());
32
33 short
34 }
35
36 #[inline]
38 pub fn as_str(&self) -> &str {
39 unsafe {
40 str::from_utf8_unchecked(
41 slice::from_raw_parts(self.value.as_ptr() as _, self.len as usize)
42 )
43 }
44 }
45}
46
47impl PartialEq for Short {
48 #[inline]
49 fn eq(&self, other: &Short) -> bool {
50 self.as_str() == other.as_str()
51 }
52}
53
54impl fmt::Debug for Short {
55 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
56 fmt::Debug::fmt(self.as_str(), f)
57 }
58}
59
60impl fmt::Display for Short {
61 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
62 fmt::Display::fmt(self.as_str(), f)
63 }
64}
65
66impl Deref for Short {
71 type Target = str;
72
73 #[inline(always)]
74 fn deref(&self) -> &str {
75 self.as_str()
76 }
77}
78
79impl From<Short> for String {
80 fn from(short: Short) -> String {
81 String::from(short.as_str())
82 }
83}
84
85impl PartialEq<str> for Short {
86 fn eq(&self, other: &str) -> bool {
87 self.as_str().eq(other)
88 }
89}
90
91impl PartialEq<Short> for str {
92 fn eq(&self, other: &Short) -> bool {
93 other.as_str().eq(self)
94 }
95}
96
97impl PartialEq<String> for Short {
98 fn eq(&self, other: &String) -> bool {
99 self.as_str().eq(other)
100 }
101}
102
103impl PartialEq<Short> for String {
104 fn eq(&self, other: &Short) -> bool {
105 other.as_str().eq(self)
106 }
107}