common_base/
bytes.rs

1// Copyright 2023 Greptime Team
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use std::ops::Deref;
16
17use serde::{Deserialize, Deserializer, Serialize, Serializer};
18
19/// Bytes buffer.
20#[derive(Debug, Default, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Deserialize, Serialize)]
21pub struct Bytes(bytes::Bytes);
22
23impl From<Bytes> for bytes::Bytes {
24    fn from(value: Bytes) -> Self {
25        value.0
26    }
27}
28
29impl From<bytes::Bytes> for Bytes {
30    fn from(bytes: bytes::Bytes) -> Bytes {
31        Bytes(bytes)
32    }
33}
34
35impl From<&[u8]> for Bytes {
36    fn from(bytes: &[u8]) -> Bytes {
37        Bytes(bytes::Bytes::copy_from_slice(bytes))
38    }
39}
40
41impl From<Vec<u8>> for Bytes {
42    fn from(bytes: Vec<u8>) -> Bytes {
43        Bytes(bytes::Bytes::from(bytes))
44    }
45}
46
47impl From<Bytes> for Vec<u8> {
48    fn from(bytes: Bytes) -> Vec<u8> {
49        bytes.0.into()
50    }
51}
52
53impl Deref for Bytes {
54    type Target = [u8];
55
56    fn deref(&self) -> &[u8] {
57        &self.0
58    }
59}
60
61impl PartialEq<Vec<u8>> for Bytes {
62    fn eq(&self, other: &Vec<u8>) -> bool {
63        self.0 == other
64    }
65}
66
67impl PartialEq<Bytes> for Vec<u8> {
68    fn eq(&self, other: &Bytes) -> bool {
69        *self == other.0
70    }
71}
72
73impl PartialEq<[u8]> for Bytes {
74    fn eq(&self, other: &[u8]) -> bool {
75        self.0 == other
76    }
77}
78
79impl PartialEq<Bytes> for [u8] {
80    fn eq(&self, other: &Bytes) -> bool {
81        self == other.0
82    }
83}
84
85/// String buffer that can hold arbitrary encoding string (only support UTF-8 now).
86///
87/// Now this buffer is restricted to only hold valid UTF-8 string (only allow constructing `StringBytes`
88/// from String or str). We may support other encoding in the future.
89#[derive(Debug, Default, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
90pub struct StringBytes(String);
91
92impl StringBytes {
93    /// View this string as UTF-8 string slice.
94    pub fn as_utf8(&self) -> &str {
95        &self.0
96    }
97
98    /// Convert this string into owned UTF-8 string.
99    pub fn into_string(self) -> String {
100        self.0
101    }
102
103    pub fn len(&self) -> usize {
104        self.0.len()
105    }
106
107    pub fn is_empty(&self) -> bool {
108        self.0.is_empty()
109    }
110}
111
112impl From<String> for StringBytes {
113    fn from(string: String) -> StringBytes {
114        StringBytes(string)
115    }
116}
117
118impl From<&str> for StringBytes {
119    fn from(string: &str) -> StringBytes {
120        StringBytes(string.to_string())
121    }
122}
123
124impl PartialEq<String> for StringBytes {
125    fn eq(&self, other: &String) -> bool {
126        &self.0 == other
127    }
128}
129
130impl PartialEq<StringBytes> for String {
131    fn eq(&self, other: &StringBytes) -> bool {
132        self == &other.0
133    }
134}
135
136impl PartialEq<str> for StringBytes {
137    fn eq(&self, other: &str) -> bool {
138        self.0.as_str() == other
139    }
140}
141
142impl PartialEq<StringBytes> for str {
143    fn eq(&self, other: &StringBytes) -> bool {
144        self == other.0
145    }
146}
147
148impl Serialize for StringBytes {
149    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
150    where
151        S: Serializer,
152    {
153        self.as_utf8().serialize(serializer)
154    }
155}
156
157// Custom Deserialize to ensure UTF-8 check is always done.
158impl<'de> Deserialize<'de> for StringBytes {
159    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
160    where
161        D: Deserializer<'de>,
162    {
163        let s = String::deserialize(deserializer)?;
164        Ok(StringBytes::from(s))
165    }
166}
167
168#[cfg(test)]
169mod tests {
170    use super::*;
171
172    fn check_bytes_deref(expect: &[u8], given: &[u8]) {
173        assert_eq!(expect, given);
174    }
175
176    #[test]
177    fn test_bytes_deref() {
178        let hello = b"hello";
179        let bytes = Bytes::from(hello.to_vec());
180        check_bytes_deref(hello, &bytes);
181    }
182
183    #[test]
184    fn test_bytes_from() {
185        let hello = b"hello".to_vec();
186        let bytes = Bytes::from(hello.clone());
187        assert_eq!(hello, bytes);
188        assert_eq!(bytes, hello);
189
190        let world: &[u8] = b"world";
191        let bytes = Bytes::from(world);
192        assert_eq!(&bytes, world);
193        assert_eq!(world, &bytes);
194    }
195
196    #[test]
197    fn test_bytes_len() {
198        let hello = b"hello".to_vec();
199        let bytes = Bytes::from(hello.clone());
200        assert_eq!(bytes.len(), hello.len());
201
202        let zero = b"".to_vec();
203        let bytes = Bytes::from(zero);
204        assert!(bytes.is_empty());
205    }
206
207    #[test]
208    fn test_string_bytes_from() {
209        let hello = "hello".to_string();
210        let bytes = StringBytes::from(hello.clone());
211        assert_eq!(hello, bytes);
212        assert_eq!(bytes, hello);
213
214        let world = "world";
215        let bytes = StringBytes::from(world);
216        assert_eq!(world, &bytes);
217        assert_eq!(&bytes, world);
218    }
219
220    #[test]
221    fn test_string_bytes_len() {
222        let hello = "hello".to_string();
223        let bytes = StringBytes::from(hello.clone());
224        assert_eq!(bytes.len(), hello.len());
225
226        let zero = String::default();
227        let bytes = StringBytes::from(zero);
228        assert!(bytes.is_empty());
229    }
230
231    fn check_str(expect: &str, given: &str) {
232        assert_eq!(expect, given);
233    }
234
235    #[test]
236    fn test_as_utf8() {
237        let hello = "hello";
238        let bytes = StringBytes::from(hello);
239        check_str(hello, bytes.as_utf8());
240    }
241}