@@ -13,102 +13,9 @@ use crate::{
1313} ;
1414
1515/// Byte string without UTF-8 validity guarantee.
16- #[ repr( transparent) ]
17- pub struct BStr ( [ u8 ] ) ;
18-
19- impl BStr {
20- /// Returns the length of this string.
21- #[ inline]
22- pub const fn len ( & self ) -> usize {
23- self . 0 . len ( )
24- }
25-
26- /// Returns `true` if the string is empty.
27- #[ inline]
28- pub const fn is_empty ( & self ) -> bool {
29- self . len ( ) == 0
30- }
31-
32- /// Creates a [`BStr`] from a `[u8]`.
33- #[ inline]
34- pub const fn from_bytes ( bytes : & [ u8 ] ) -> & Self {
35- // SAFETY: `BStr` is transparent to `[u8]`.
36- unsafe { & * ( bytes as * const [ u8 ] as * const BStr ) }
37- }
38- }
39-
40- impl fmt:: Display for BStr {
41- /// Formats printable ASCII characters, escaping the rest.
42- ///
43- /// ```
44- /// # use kernel::{fmt, b_str, str::{BStr, CString}};
45- /// let ascii = b_str!("Hello, BStr!");
46- /// let s = CString::try_from_fmt(fmt!("{}", ascii)).unwrap();
47- /// assert_eq!(s.as_bytes(), "Hello, BStr!".as_bytes());
48- ///
49- /// let non_ascii = b_str!("🦀");
50- /// let s = CString::try_from_fmt(fmt!("{}", non_ascii)).unwrap();
51- /// assert_eq!(s.as_bytes(), "\\xf0\\x9f\\xa6\\x80".as_bytes());
52- /// ```
53- fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
54- for & b in & self . 0 {
55- match b {
56- // Common escape codes.
57- b'\t' => f. write_str ( "\\ t" ) ?,
58- b'\n' => f. write_str ( "\\ n" ) ?,
59- b'\r' => f. write_str ( "\\ r" ) ?,
60- // Printable characters.
61- 0x20 ..=0x7e => f. write_char ( b as char ) ?,
62- _ => write ! ( f, "\\ x{:02x}" , b) ?,
63- }
64- }
65- Ok ( ( ) )
66- }
67- }
68-
69- impl fmt:: Debug for BStr {
70- /// Formats printable ASCII characters with a double quote on either end,
71- /// escaping the rest.
72- ///
73- /// ```
74- /// # use kernel::{fmt, b_str, str::{BStr, CString}};
75- /// // Embedded double quotes are escaped.
76- /// let ascii = b_str!("Hello, \"BStr\"!");
77- /// let s = CString::try_from_fmt(fmt!("{:?}", ascii)).unwrap();
78- /// assert_eq!(s.as_bytes(), "\"Hello, \\\"BStr\\\"!\"".as_bytes());
79- ///
80- /// let non_ascii = b_str!("😺");
81- /// let s = CString::try_from_fmt(fmt!("{:?}", non_ascii)).unwrap();
82- /// assert_eq!(s.as_bytes(), "\"\\xf0\\x9f\\x98\\xba\"".as_bytes());
83- /// ```
84- fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
85- f. write_char ( '"' ) ?;
86- for & b in & self . 0 {
87- match b {
88- // Common escape codes.
89- b'\t' => f. write_str ( "\\ t" ) ?,
90- b'\n' => f. write_str ( "\\ n" ) ?,
91- b'\r' => f. write_str ( "\\ r" ) ?,
92- // String escape characters.
93- b'\"' => f. write_str ( "\\ \" " ) ?,
94- b'\\' => f. write_str ( "\\ \\ " ) ?,
95- // Printable characters.
96- 0x20 ..=0x7e => f. write_char ( b as char ) ?,
97- _ => write ! ( f, "\\ x{:02x}" , b) ?,
98- }
99- }
100- f. write_char ( '"' )
101- }
102- }
103-
104- impl Deref for BStr {
105- type Target = [ u8 ] ;
106-
107- #[ inline]
108- fn deref ( & self ) -> & Self :: Target {
109- & self . 0
110- }
111- }
16+ ///
17+ /// `BStr` is simply an alias to `[u8]`, but has a more evident semantical meaning.
18+ pub type BStr = [ u8 ] ;
11219
11320/// Creates a new [`BStr`] from a string literal.
11421///
@@ -126,7 +33,7 @@ impl Deref for BStr {
12633macro_rules! b_str {
12734 ( $str: literal) => { {
12835 const S : & ' static str = $str;
129- const C : & ' static $crate:: str :: BStr = $crate :: str :: BStr :: from_bytes ( S . as_bytes( ) ) ;
36+ const C : & ' static $crate:: str :: BStr = S . as_bytes( ) ;
13037 C
13138 } } ;
13239}
@@ -364,7 +271,7 @@ impl fmt::Debug for CStr {
364271impl AsRef < BStr > for CStr {
365272 #[ inline]
366273 fn as_ref ( & self ) -> & BStr {
367- BStr :: from_bytes ( self . as_bytes ( ) )
274+ self . as_bytes ( )
368275 }
369276}
370277
@@ -373,7 +280,7 @@ impl Deref for CStr {
373280
374281 #[ inline]
375282 fn deref ( & self ) -> & Self :: Target {
376- self . as_ref ( )
283+ self . as_bytes ( )
377284 }
378285}
379286
@@ -420,7 +327,7 @@ where
420327
421328 #[ inline]
422329 fn index ( & self , index : Idx ) -> & Self :: Output {
423- & self . as_ref ( ) [ index]
330+ & self . as_bytes ( ) [ index]
424331 }
425332}
426333
@@ -450,21 +357,6 @@ macro_rules! c_str {
450357#[ cfg( test) ]
451358mod tests {
452359 use super :: * ;
453- use alloc:: format;
454-
455- const ALL_ASCII_CHARS : & ' static str =
456- "\\ x01\\ x02\\ x03\\ x04\\ x05\\ x06\\ x07\\ x08\\ x09\\ x0a\\ x0b\\ x0c\\ x0d\\ x0e\\ x0f\
457- \\ x10\\ x11\\ x12\\ x13\\ x14\\ x15\\ x16\\ x17\\ x18\\ x19\\ x1a\\ x1b\\ x1c\\ x1d\\ x1e\\ x1f \
458- !\" #$%&'()*+,-./0123456789:;<=>?@\
459- ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\ ]^_`abcdefghijklmnopqrstuvwxyz{|}~\\ x7f\
460- \\ x80\\ x81\\ x82\\ x83\\ x84\\ x85\\ x86\\ x87\\ x88\\ x89\\ x8a\\ x8b\\ x8c\\ x8d\\ x8e\\ x8f\
461- \\ x90\\ x91\\ x92\\ x93\\ x94\\ x95\\ x96\\ x97\\ x98\\ x99\\ x9a\\ x9b\\ x9c\\ x9d\\ x9e\\ x9f\
462- \\ xa0\\ xa1\\ xa2\\ xa3\\ xa4\\ xa5\\ xa6\\ xa7\\ xa8\\ xa9\\ xaa\\ xab\\ xac\\ xad\\ xae\\ xaf\
463- \\ xb0\\ xb1\\ xb2\\ xb3\\ xb4\\ xb5\\ xb6\\ xb7\\ xb8\\ xb9\\ xba\\ xbb\\ xbc\\ xbd\\ xbe\\ xbf\
464- \\ xc0\\ xc1\\ xc2\\ xc3\\ xc4\\ xc5\\ xc6\\ xc7\\ xc8\\ xc9\\ xca\\ xcb\\ xcc\\ xcd\\ xce\\ xcf\
465- \\ xd0\\ xd1\\ xd2\\ xd3\\ xd4\\ xd5\\ xd6\\ xd7\\ xd8\\ xd9\\ xda\\ xdb\\ xdc\\ xdd\\ xde\\ xdf\
466- \\ xe0\\ xe1\\ xe2\\ xe3\\ xe4\\ xe5\\ xe6\\ xe7\\ xe8\\ xe9\\ xea\\ xeb\\ xec\\ xed\\ xee\\ xef\
467- \\ xf0\\ xf1\\ xf2\\ xf3\\ xf4\\ xf5\\ xf6\\ xf7\\ xf8\\ xf9\\ xfa\\ xfb\\ xfc\\ xfd\\ xfe\\ xff";
468360
469361 #[ test]
470362 fn test_cstr_to_str ( ) {
@@ -489,69 +381,6 @@ mod tests {
489381 let unchecked_str = unsafe { checked_cstr. as_str_unchecked ( ) } ;
490382 assert_eq ! ( unchecked_str, "🐧" ) ;
491383 }
492-
493- #[ test]
494- fn test_cstr_display ( ) {
495- let hello_world = CStr :: from_bytes_with_nul ( b"hello, world!\0 " ) . unwrap ( ) ;
496- assert_eq ! ( format!( "{}" , hello_world) , "hello, world!" ) ;
497- let non_printables = CStr :: from_bytes_with_nul ( b"\x01 \x09 \x0a \0 " ) . unwrap ( ) ;
498- assert_eq ! ( format!( "{}" , non_printables) , "\\ x01\\ x09\\ x0a" ) ;
499- let non_ascii = CStr :: from_bytes_with_nul ( b"d\xe9 j\xe0 vu\0 " ) . unwrap ( ) ;
500- assert_eq ! ( format!( "{}" , non_ascii) , "d\\ xe9j\\ xe0 vu" ) ;
501- let good_bytes = CStr :: from_bytes_with_nul ( b"\xf0 \x9f \xa6 \x80 \0 " ) . unwrap ( ) ;
502- assert_eq ! ( format!( "{}" , good_bytes) , "\\ xf0\\ x9f\\ xa6\\ x80" ) ;
503- }
504-
505- #[ test]
506- fn test_cstr_display_all_bytes ( ) {
507- let mut bytes: [ u8 ; 256 ] = [ 0 ; 256 ] ;
508- // fill `bytes` with [1..=255] + [0]
509- for i in u8:: MIN ..=u8:: MAX {
510- bytes[ i as usize ] = i. wrapping_add ( 1 ) ;
511- }
512- let cstr = CStr :: from_bytes_with_nul ( & bytes) . unwrap ( ) ;
513- assert_eq ! ( format!( "{}" , cstr) , ALL_ASCII_CHARS ) ;
514- }
515-
516- #[ test]
517- fn test_cstr_debug ( ) {
518- let hello_world = CStr :: from_bytes_with_nul ( b"hello, world!\0 " ) . unwrap ( ) ;
519- assert_eq ! ( format!( "{:?}" , hello_world) , "\" hello, world!\" " ) ;
520- let non_printables = CStr :: from_bytes_with_nul ( b"\x01 \x09 \x0a \0 " ) . unwrap ( ) ;
521- assert_eq ! ( format!( "{:?}" , non_printables) , "\" \\ x01\\ x09\\ x0a\" " ) ;
522- let non_ascii = CStr :: from_bytes_with_nul ( b"d\xe9 j\xe0 vu\0 " ) . unwrap ( ) ;
523- assert_eq ! ( format!( "{:?}" , non_ascii) , "\" d\\ xe9j\\ xe0 vu\" " ) ;
524- let good_bytes = CStr :: from_bytes_with_nul ( b"\xf0 \x9f \xa6 \x80 \0 " ) . unwrap ( ) ;
525- assert_eq ! ( format!( "{:?}" , good_bytes) , "\" \\ xf0\\ x9f\\ xa6\\ x80\" " ) ;
526- }
527-
528- #[ test]
529- fn test_bstr_display ( ) {
530- let hello_world = BStr :: from_bytes ( b"hello, world!" ) ;
531- assert_eq ! ( format!( "{}" , hello_world) , "hello, world!" ) ;
532- let escapes = BStr :: from_bytes ( b"_\t _\n _\r _\\ _\' _\" _" ) ;
533- assert_eq ! ( format!( "{}" , escapes) , "_\\ t_\\ n_\\ r_\\ _'_\" _" ) ;
534- let others = BStr :: from_bytes ( b"\x01 " ) ;
535- assert_eq ! ( format!( "{}" , others) , "\\ x01" ) ;
536- let non_ascii = BStr :: from_bytes ( b"d\xe9 j\xe0 vu" ) ;
537- assert_eq ! ( format!( "{}" , non_ascii) , "d\\ xe9j\\ xe0 vu" ) ;
538- let good_bytes = BStr :: from_bytes ( b"\xf0 \x9f \xa6 \x80 " ) ;
539- assert_eq ! ( format!( "{}" , good_bytes) , "\\ xf0\\ x9f\\ xa6\\ x80" ) ;
540- }
541-
542- #[ test]
543- fn test_bstr_debug ( ) {
544- let hello_world = BStr :: from_bytes ( b"hello, world!" ) ;
545- assert_eq ! ( format!( "{:?}" , hello_world) , "\" hello, world!\" " ) ;
546- let escapes = BStr :: from_bytes ( b"_\t _\n _\r _\\ _\' _\" _" ) ;
547- assert_eq ! ( format!( "{:?}" , escapes) , "\" _\\ t_\\ n_\\ r_\\ \\ _'_\\ \" _\" " ) ;
548- let others = BStr :: from_bytes ( b"\x01 " ) ;
549- assert_eq ! ( format!( "{:?}" , others) , "\" \\ x01\" " ) ;
550- let non_ascii = BStr :: from_bytes ( b"d\xe9 j\xe0 vu" ) ;
551- assert_eq ! ( format!( "{:?}" , non_ascii) , "\" d\\ xe9j\\ xe0 vu\" " ) ;
552- let good_bytes = BStr :: from_bytes ( b"\xf0 \x9f \xa6 \x80 " ) ;
553- assert_eq ! ( format!( "{:?}" , good_bytes) , "\" \\ xf0\\ x9f\\ xa6\\ x80\" " ) ;
554- }
555384}
556385
557386/// Allows formatting of [`fmt::Arguments`] into a raw buffer.
0 commit comments