1use std::{
2 cmp::Ordering,
3 hash::{Hash, Hasher},
4 rc::Rc,
5};
6
7pub trait ToBytes<'a> {
8 fn to_bytes(self) -> Bytes<'a>;
9}
10
11impl<'a> ToBytes<'a> for &'a [u8] {
12 fn to_bytes(self) -> Bytes<'a> {
13 Bytes::Slice(self)
14 }
15}
16
17impl<'a> ToBytes<'a> for &'a str {
18 fn to_bytes(self) -> Bytes<'a> {
19 Bytes::Slice(self.as_bytes())
20 }
21}
22
23macro_rules! byte_array_to_bytes {
24 ($($n:expr),*) => (
25 $(
26 impl<'a> ToBytes<'a> for [u8; $n] {
27 fn to_bytes(self) -> Bytes<'a> {
28 Bytes::Bytes(bytes::Bytes::copy_from_slice(&self))
29 }
30 }
31 )*
32)
33}
34
35byte_array_to_bytes!(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
39
40impl<'a> ToBytes<'a> for String {
41 fn to_bytes(self) -> Bytes<'a> {
42 Bytes::String(Rc::new(self))
43 }
44}
45
46impl<'a> ToBytes<'a> for Vec<u8> {
47 fn to_bytes(self) -> Bytes<'a> {
48 Bytes::Vec(Rc::new(self))
49 }
50}
51
52impl<'a> ToBytes<'a> for bytes::Bytes {
53 fn to_bytes(self) -> Bytes<'a> {
54 Bytes::Bytes(self)
55 }
56}
57
58impl<'a> ToBytes<'a> for &bytes::Bytes {
59 fn to_bytes(self) -> Bytes<'a> {
60 Bytes::Bytes(self.clone())
61 }
62}
63
64impl<'a> ToBytes<'a> for Bytes<'a> {
65 fn to_bytes(self) -> Bytes<'a> {
66 self
67 }
68}
69
70impl<'a> ToBytes<'a> for &Bytes<'a> {
71 fn to_bytes(self) -> Bytes<'a> {
72 self.clone()
73 }
74}
75
76#[derive(Debug, Clone)]
77pub enum Bytes<'a> {
78 Slice(&'a [u8]),
79 Bytes(bytes::Bytes),
80 Vec(Rc<Vec<u8>>),
81 String(Rc<String>),
82}
83
84impl<'a> Bytes<'a> {
85 pub fn size(&self) -> usize {
86 match self {
87 Self::Slice(s) => s.len(),
88 Self::Bytes(b) => b.len(),
89 Self::Vec(v) => v.len(),
90 Self::String(s) => s.len(),
91 }
92 }
93}
94
95impl<'a> AsRef<[u8]> for Bytes<'a> {
96 fn as_ref(&self) -> &[u8] {
97 match self {
98 Self::Slice(s) => s,
99 Self::Bytes(b) => b,
100 Self::Vec(v) => v.as_slice(),
101 Self::String(s) => s.as_bytes(),
102 }
103 }
104}
105
106impl<'a> Ord for Bytes<'a> {
107 fn cmp(&self, other: &Self) -> Ordering {
108 let a = self.as_ref();
109 let b = other.as_ref();
110 a.cmp(b)
111 }
112}
113
114impl<'a> PartialOrd for Bytes<'a> {
115 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
116 Some(self.cmp(other))
117 }
118}
119
120impl<'a> PartialEq for Bytes<'a> {
121 fn eq(&self, other: &Self) -> bool {
122 let a = self.as_ref();
123 let b = other.as_ref();
124 a.eq(b)
125 }
126}
127
128impl<'a> Eq for Bytes<'a> {}
129
130impl<'a> Hash for Bytes<'a> {
131 fn hash<H: Hasher>(&self, state: &mut H) {
132 let a = self.as_ref();
133 a.hash(state);
134 }
135}
136
137#[cfg(test)]
138mod tests {
139 use super::*;
140
141 #[test]
142 fn from_vec() {
143 let vec: Vec<u8> = vec![0, 0, 0];
144 let ptr = vec.as_slice()[0] as *const u8;
145 let b: Bytes = vec.to_bytes();
146 let ptr2 = b.as_ref()[0] as *const u8;
147 assert!(ptr == ptr2);
148 }
149
150 #[test]
151 fn from_str() {
152 let s = "abc";
153 let ptr = s.as_bytes()[0] as *const u8;
154 let b: Bytes = s.to_bytes();
155 let ptr2 = b.as_ref()[0] as *const u8;
156 assert!(ptr == ptr2);
157 }
158}