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