/rust/registry/src/index.crates.io-1949cf8c6b5b557f/http-1.3.1/src/byte_str.rs
Line | Count | Source |
1 | | use bytes::Bytes; |
2 | | |
3 | | use std::{ops, str}; |
4 | | |
5 | | #[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] |
6 | | pub(crate) struct ByteStr { |
7 | | // Invariant: bytes contains valid UTF-8 |
8 | | bytes: Bytes, |
9 | | } |
10 | | |
11 | | impl ByteStr { |
12 | | #[inline] |
13 | 435k | pub fn new() -> ByteStr { |
14 | 435k | ByteStr { |
15 | 435k | // Invariant: the empty slice is trivially valid UTF-8. |
16 | 435k | bytes: Bytes::new(), |
17 | 435k | } |
18 | 435k | } |
19 | | |
20 | | #[inline] |
21 | 430k | pub const fn from_static(val: &'static str) -> ByteStr { |
22 | 430k | ByteStr { |
23 | 430k | // Invariant: val is a str so contains valid UTF-8. |
24 | 430k | bytes: Bytes::from_static(val.as_bytes()), |
25 | 430k | } |
26 | 430k | } |
27 | | |
28 | | #[inline] |
29 | | /// ## Panics |
30 | | /// In a debug build this will panic if `bytes` is not valid UTF-8. |
31 | | /// |
32 | | /// ## Safety |
33 | | /// `bytes` must contain valid UTF-8. In a release build it is undefined |
34 | | /// behavior to call this with `bytes` that is not valid UTF-8. |
35 | 1.47M | pub unsafe fn from_utf8_unchecked(bytes: Bytes) -> ByteStr { |
36 | 1.47M | if cfg!(debug_assertions) { |
37 | 0 | match str::from_utf8(&bytes) { |
38 | 0 | Ok(_) => (), |
39 | 0 | Err(err) => panic!( |
40 | 0 | "ByteStr::from_utf8_unchecked() with invalid bytes; error = {}, bytes = {:?}", |
41 | | err, bytes |
42 | | ), |
43 | | } |
44 | 1.47M | } |
45 | | // Invariant: assumed by the safety requirements of this function. |
46 | 1.47M | ByteStr { bytes } |
47 | 1.47M | } |
48 | | |
49 | 95 | pub(crate) fn from_utf8(bytes: Bytes) -> Result<ByteStr, std::str::Utf8Error> { |
50 | 95 | str::from_utf8(&bytes)?; |
51 | | // Invariant: just checked is utf8 |
52 | 26 | Ok(ByteStr { bytes }) |
53 | 95 | } |
54 | | } |
55 | | |
56 | | impl ops::Deref for ByteStr { |
57 | | type Target = str; |
58 | | |
59 | | #[inline] |
60 | 2.35M | fn deref(&self) -> &str { |
61 | 2.35M | let b: &[u8] = self.bytes.as_ref(); |
62 | | // Safety: the invariant of `bytes` is that it contains valid UTF-8. |
63 | 2.35M | unsafe { str::from_utf8_unchecked(b) } |
64 | 2.35M | } <http::byte_str::ByteStr as core::ops::deref::Deref>::deref Line | Count | Source | 60 | 1.13M | fn deref(&self) -> &str { | 61 | 1.13M | let b: &[u8] = self.bytes.as_ref(); | 62 | | // Safety: the invariant of `bytes` is that it contains valid UTF-8. | 63 | 1.13M | unsafe { str::from_utf8_unchecked(b) } | 64 | 1.13M | } |
<http::byte_str::ByteStr as core::ops::deref::Deref>::deref Line | Count | Source | 60 | 1.21M | fn deref(&self) -> &str { | 61 | 1.21M | let b: &[u8] = self.bytes.as_ref(); | 62 | | // Safety: the invariant of `bytes` is that it contains valid UTF-8. | 63 | 1.21M | unsafe { str::from_utf8_unchecked(b) } | 64 | 1.21M | } |
|
65 | | } |
66 | | |
67 | | impl From<String> for ByteStr { |
68 | | #[inline] |
69 | 0 | fn from(src: String) -> ByteStr { |
70 | 0 | ByteStr { |
71 | 0 | // Invariant: src is a String so contains valid UTF-8. |
72 | 0 | bytes: Bytes::from(src), |
73 | 0 | } |
74 | 0 | } |
75 | | } |
76 | | |
77 | | impl<'a> From<&'a str> for ByteStr { |
78 | | #[inline] |
79 | 0 | fn from(src: &'a str) -> ByteStr { |
80 | 0 | ByteStr { |
81 | 0 | // Invariant: src is a str so contains valid UTF-8. |
82 | 0 | bytes: Bytes::copy_from_slice(src.as_bytes()), |
83 | 0 | } |
84 | 0 | } |
85 | | } |
86 | | |
87 | | impl From<ByteStr> for Bytes { |
88 | 0 | fn from(src: ByteStr) -> Self { |
89 | 0 | src.bytes |
90 | 0 | } |
91 | | } |