1use bytes::Bytes;
2
3use std::{ops, str};
4
5#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
6pub(crate) struct ByteStr {
7 bytes: Bytes,
9}
10
11impl ByteStr {
12 #[inline]
13 pub fn new() -> ByteStr {
14 ByteStr {
15 bytes: Bytes::new(),
17 }
18 }
19
20 #[inline]
21 pub const fn from_static(val: &'static str) -> ByteStr {
22 ByteStr {
23 bytes: Bytes::from_static(val.as_bytes()),
25 }
26 }
27
28 #[inline]
29 pub unsafe fn from_utf8_unchecked(bytes: Bytes) -> ByteStr {
36 if cfg!(debug_assertions) {
37 match str::from_utf8(&bytes) {
38 Ok(_) => (),
39 Err(err) => panic!(
40 "ByteStr::from_utf8_unchecked() with invalid bytes; error = {}, bytes = {:?}",
41 err, bytes
42 ),
43 }
44 }
45 ByteStr { bytes }
47 }
48
49 pub(crate) fn from_utf8(bytes: Bytes) -> Result<ByteStr, std::str::Utf8Error> {
50 str::from_utf8(&bytes)?;
51 Ok(ByteStr { bytes })
53 }
54}
55
56impl ops::Deref for ByteStr {
57 type Target = str;
58
59 #[inline]
60 fn deref(&self) -> &str {
61 let b: &[u8] = self.bytes.as_ref();
62 unsafe { str::from_utf8_unchecked(b) }
64 }
65}
66
67impl From<String> for ByteStr {
68 #[inline]
69 fn from(src: String) -> ByteStr {
70 ByteStr {
71 bytes: Bytes::from(src),
73 }
74 }
75}
76
77impl<'a> From<&'a str> for ByteStr {
78 #[inline]
79 fn from(src: &'a str) -> ByteStr {
80 ByteStr {
81 bytes: Bytes::copy_from_slice(src.as_bytes()),
83 }
84 }
85}
86
87impl From<ByteStr> for Bytes {
88 fn from(src: ByteStr) -> Self {
89 src.bytes
90 }
91}