22// SPDX-License-Identifier: Apache-2.0
33
44use crate :: Bytes ;
5- #[ cfg( all ( feature = "bytes_string" , feature = " serde") ) ]
5+ #[ cfg( feature = "serde" ) ]
66use serde:: ser:: { Serialize , Serializer } ;
77use std:: borrow:: Borrow ;
88use std:: str:: Utf8Error ;
99
10- #[ cfg( feature = "bytes_string" ) ]
11- pub struct BufferWrapper < ' a , ' b > {
12- buffer : Bytes ,
13- pub underlying : & ' a mut & ' b [ u8 ] ,
14- }
15-
16- #[ cfg( feature = "bytes_string" ) ]
17- impl < ' a , ' b > BufferWrapper < ' a , ' b > {
18- /// Creates a new `BufferWrapper` from a `tinybytes::Bytes` instance.
19- ///
20- /// # Arguments
21- ///
22- /// * `buffer` - A `tinybytes::Bytes` instance to be wrapped.
23- ///
24- /// # Returns
25- ///
26- /// A new `BufferWrapper` instance containing the provided buffer.
27- pub fn new ( buffer : Bytes , underlying : & ' a mut & ' b [ u8 ] ) -> Self {
28- BufferWrapper { buffer, underlying }
29- }
30-
31- /// Creates a `BytesString` from a slice of bytes within the wrapped buffer.
32- ///
33- /// This function validates that the provided slice is valid UTF-8. If the slice is not valid
34- /// UTF-8, an error is returned.
35- ///
36- /// # Arguments
37- ///
38- /// * `slice` - A byte slice that will be converted into a `BytesString`.
39- ///
40- /// # Returns
41- ///
42- /// A `Result` containing the `BytesString` if the slice is valid UTF-8, or a `Utf8Error` if
43- /// the slice is not valid UTF-8.
44- ///
45- /// # Errors
46- ///
47- /// Returns a `Utf8Error` if the bytes are not valid UTF-8.
48- pub fn create_bytes_string ( & self , slice : & [ u8 ] ) -> Result < BytesString , std:: str:: Utf8Error > {
49- BytesString :: from_bytes ( self . buffer . slice_ref ( slice) . expect ( "Invalid slice" ) )
50- }
51-
52- /// Creates a `BytesString` from a slice of bytes within the wrapped buffer without validating
53- /// the bytes.
54- ///
55- /// This function does not perform any validation on the provided bytes, and assumes that the
56- /// bytes are valid UTF-8. If the bytes are not valid UTF-8, the behavior is undefined.
57- ///
58- /// # Arguments
59- ///
60- /// * `slice` - A byte slice that will be converted into a `BytesString`.
61- ///
62- /// # Safety
63- ///
64- /// This function is unsafe because it assumes the bytes are valid UTF-8. If the bytes are not
65- /// valid UTF-8, the behavior is undefined.
66- pub unsafe fn create_bytes_string_unchecked ( & self , slice : & [ u8 ] ) -> BytesString {
67- BytesString :: from_bytes_unchecked ( self . buffer . slice_ref ( slice) . expect ( "Invalid slice" ) )
68- }
69- }
70-
71- #[ cfg( feature = "bytes_string" ) ]
7210#[ derive( Clone , Debug , Eq , Hash , PartialEq ) ]
7311pub struct BytesString {
7412 bytes : Bytes ,
7513}
7614
77- #[ cfg( all ( feature = "bytes_string" , feature = " serde") ) ]
15+ #[ cfg( feature = "serde" ) ]
7816impl Serialize for BytesString {
7917 fn serialize < S > ( & self , serializer : S ) -> Result < S :: Ok , S :: Error >
8018 where
8119 S : Serializer ,
8220 {
83- // This should be safe because we have already validated that the bytes are valid UTF-8 when
84- // creating the BytesString.
85- unsafe { serializer. serialize_str ( self . as_str_unchecked ( ) ) }
21+ serializer. serialize_str ( self . as_str ( ) )
8622 }
8723}
8824
89- #[ cfg( feature = "bytes_string" ) ]
9025impl BytesString {
9126 /// Creates a `BytesString` from a slice of bytes.
9227 ///
@@ -105,7 +40,7 @@ impl BytesString {
10540 /// # Errors
10641 ///
10742 /// Returns a `Utf8Error` if the bytes are not valid UTF-8.
108- pub fn from_slice ( slice : & [ u8 ] ) -> Result < BytesString , std :: str :: Utf8Error > {
43+ pub fn from_slice ( slice : & [ u8 ] ) -> Result < BytesString , Utf8Error > {
10944 std:: str:: from_utf8 ( slice) ?;
11045 Ok ( BytesString {
11146 bytes : Bytes :: copy_from_slice ( slice) ,
@@ -129,11 +64,26 @@ impl BytesString {
12964 /// # Errors
13065 ///
13166 /// Returns a `Utf8Error` if the bytes are not valid UTF-8.
132- pub fn from_bytes ( bytes : Bytes ) -> Result < BytesString , std :: str :: Utf8Error > {
67+ pub fn from_bytes ( bytes : Bytes ) -> Result < BytesString , Utf8Error > {
13368 std:: str:: from_utf8 ( & bytes) ?;
13469 Ok ( BytesString { bytes } )
13570 }
13671
72+ /// Creates a `BytesString` from a string slice within the given buffer.
73+ ///
74+ /// # Arguments
75+ ///
76+ /// * `bytes` - A `tinybytes::Bytes` instance that will be converted into a `BytesString`.
77+ /// * `slice` - The string slice pointing into the given bytes that will form the `BytesString`.
78+ pub fn from_bytes_slice ( bytes : & Bytes , slice : & str ) -> BytesString {
79+ // SAFETY: This is safe as a str slice is definitely a valid UTF-8 slice.
80+ unsafe {
81+ BytesString :: from_bytes_unchecked (
82+ bytes. slice_ref ( slice. as_bytes ( ) ) . expect ( "Invalid slice" ) ,
83+ )
84+ }
85+ }
86+
13787 /// Creates a `BytesString` from a `tinybytes::Bytes` instance without validating the bytes.
13888 ///
13989 /// This function does not perform any validation on the provided bytes, and assumes that the
@@ -147,37 +97,20 @@ impl BytesString {
14797 ///
14898 /// This function is unsafe because it assumes the bytes are valid UTF-8. If the bytes are not
14999 /// valid UTF-8, the behavior is undefined.
150- pub fn from_bytes_unchecked ( bytes : Bytes ) -> BytesString {
100+ pub unsafe fn from_bytes_unchecked ( bytes : Bytes ) -> BytesString {
151101 BytesString { bytes }
152102 }
153103
154- /// Returns the string slice representation of the `BytesString`. The slice is checked to be
155- /// valid UTF-8. If you use `from_bytes` or `from_slice` this check was already performed and
156- /// you may want to use `as_str_unchecked` instead.
157- ///
158- /// # Errors
159- ///
160- /// Returns a `Utf8Error` if the bytes are not valid UTF-8.
161- pub fn as_str ( & self ) -> Result < & str , Utf8Error > {
162- std:: str:: from_utf8 ( & self . bytes )
163- }
164-
165- /// Returns the string slice representation of the `BytesString` without validating the bytes.
104+ /// Returns the string slice representation of the `BytesString` (without validating the bytes).
166105 /// Typically, you should use `from_slice` or `from_bytes` when creating a BytesString to
167106 /// ensure the bytes are valid UTF-8 (if the bytes haven't already been validated by other
168107 /// means) so further validation may be unnecessary.
169- ///
170- /// # Safety
171- ///
172- /// This function is unsafe because it assumes the bytes are valid UTF-8. If the bytes are not
173- /// valid UTF-8, the behavior is undefined.
174- pub unsafe fn as_str_unchecked ( & self ) -> & str {
175- // SAFETY: This is unsafe and assumes the bytes are valid UTF-8.
108+ pub fn as_str ( & self ) -> & str {
109+ // SAFETY: We assume all BytesStrings are valid UTF-8.
176110 unsafe { std:: str:: from_utf8_unchecked ( & self . bytes ) }
177111 }
178112}
179113
180- #[ cfg( feature = "bytes_string" ) ]
181114impl Default for BytesString {
182115 fn default ( ) -> Self {
183116 BytesString {
@@ -186,25 +119,21 @@ impl Default for BytesString {
186119 }
187120}
188121
189- #[ cfg( feature = "bytes_string" ) ]
190122impl Borrow < str > for BytesString {
191123 fn borrow ( & self ) -> & str {
192- // This is safe because we have already validated that the bytes are valid UTF-8 when
193- // creating the BytesString.
194- unsafe { self . as_str_unchecked ( ) }
124+ self . as_str ( )
195125 }
196126}
197127
198128#[ cfg( test) ]
199129mod tests {
200130 use super :: * ;
201- use serde_json;
202131
203132 #[ test]
204133 fn test_from_slice ( ) {
205134 let slice = b"hello" ;
206135 let bytes_string = BytesString :: from_slice ( slice) . unwrap ( ) ;
207- assert_eq ! ( bytes_string. as_str( ) . unwrap ( ) , "hello" ) ;
136+ assert_eq ! ( bytes_string. as_str( ) , "hello" ) ;
208137 }
209138
210139 #[ test]
@@ -218,7 +147,7 @@ mod tests {
218147 fn test_from_bytes ( ) {
219148 let bytes = Bytes :: copy_from_slice ( b"world" ) ;
220149 let bytes_string = BytesString :: from_bytes ( bytes) . unwrap ( ) ;
221- assert_eq ! ( bytes_string. as_str( ) . unwrap ( ) , "world" ) ;
150+ assert_eq ! ( bytes_string. as_str( ) , "world" ) ;
222151 }
223152
224153 #[ test]
@@ -231,14 +160,14 @@ mod tests {
231160 #[ test]
232161 fn test_from_bytes_unchecked ( ) {
233162 let bytes = Bytes :: copy_from_slice ( b"unchecked" ) ;
234- let bytes_string = BytesString :: from_bytes_unchecked ( bytes) ;
235- assert_eq ! ( bytes_string. as_str( ) . unwrap ( ) , "unchecked" ) ;
163+ let bytes_string = unsafe { BytesString :: from_bytes_unchecked ( bytes) } ;
164+ assert_eq ! ( bytes_string. as_str( ) , "unchecked" ) ;
236165 }
237166
238167 #[ test]
239168 fn test_as_str ( ) {
240169 let bytes_string = BytesString :: from_slice ( b"test" ) . unwrap ( ) ;
241- assert_eq ! ( bytes_string. as_str( ) . unwrap ( ) , "test" ) ;
170+ assert_eq ! ( bytes_string. as_str( ) , "test" ) ;
242171 }
243172
244173 #[ test]
@@ -251,7 +180,7 @@ mod tests {
251180 #[ test]
252181 fn test_default ( ) {
253182 let bytes_string: BytesString = Default :: default ( ) ;
254- assert_eq ! ( bytes_string. as_str( ) . unwrap ( ) , "" ) ;
183+ assert_eq ! ( bytes_string. as_str( ) , "" ) ;
255184 }
256185
257186 #[ test]
0 commit comments