@@ -10,102 +10,9 @@ use core::ops::{self, Deref, DerefMut, Index};
1010use crate :: error:: { code:: * , Error } ;
1111
1212/// Byte string without UTF-8 validity guarantee.
13- #[ repr( transparent) ]
14- pub struct BStr ( [ u8 ] ) ;
15-
16- impl BStr {
17- /// Returns the length of this string.
18- #[ inline]
19- pub const fn len ( & self ) -> usize {
20- self . 0 . len ( )
21- }
22-
23- /// Returns `true` if the string is empty.
24- #[ inline]
25- pub const fn is_empty ( & self ) -> bool {
26- self . len ( ) == 0
27- }
28-
29- /// Creates a [`BStr`] from a `[u8]`.
30- #[ inline]
31- pub const fn from_bytes ( bytes : & [ u8 ] ) -> & Self {
32- // SAFETY: `BStr` is transparent to `[u8]`.
33- unsafe { & * ( bytes as * const [ u8 ] as * const BStr ) }
34- }
35- }
36-
37- impl fmt:: Display for BStr {
38- /// Formats printable ASCII characters, escaping the rest.
39- ///
40- /// ```
41- /// # use kernel::{fmt, b_str, str::{BStr, CString}};
42- /// let ascii = b_str!("Hello, BStr!");
43- /// let s = CString::try_from_fmt(fmt!("{}", ascii)).unwrap();
44- /// assert_eq!(s.as_bytes(), "Hello, BStr!".as_bytes());
45- ///
46- /// let non_ascii = b_str!("🦀");
47- /// let s = CString::try_from_fmt(fmt!("{}", non_ascii)).unwrap();
48- /// assert_eq!(s.as_bytes(), "\\xf0\\x9f\\xa6\\x80".as_bytes());
49- /// ```
50- fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
51- for & b in & self . 0 {
52- match b {
53- // Common escape codes.
54- b'\t' => f. write_str ( "\\ t" ) ?,
55- b'\n' => f. write_str ( "\\ n" ) ?,
56- b'\r' => f. write_str ( "\\ r" ) ?,
57- // Printable characters.
58- 0x20 ..=0x7e => f. write_char ( b as char ) ?,
59- _ => write ! ( f, "\\ x{:02x}" , b) ?,
60- }
61- }
62- Ok ( ( ) )
63- }
64- }
65-
66- impl fmt:: Debug for BStr {
67- /// Formats printable ASCII characters with a double quote on either end,
68- /// escaping the rest.
69- ///
70- /// ```
71- /// # use kernel::{fmt, b_str, str::{BStr, CString}};
72- /// // Embedded double quotes are escaped.
73- /// let ascii = b_str!("Hello, \"BStr\"!");
74- /// let s = CString::try_from_fmt(fmt!("{:?}", ascii)).unwrap();
75- /// assert_eq!(s.as_bytes(), "\"Hello, \\\"BStr\\\"!\"".as_bytes());
76- ///
77- /// let non_ascii = b_str!("😺");
78- /// let s = CString::try_from_fmt(fmt!("{:?}", non_ascii)).unwrap();
79- /// assert_eq!(s.as_bytes(), "\"\\xf0\\x9f\\x98\\xba\"".as_bytes());
80- /// ```
81- fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
82- f. write_char ( '"' ) ?;
83- for & b in & self . 0 {
84- match b {
85- // Common escape codes.
86- b'\t' => f. write_str ( "\\ t" ) ?,
87- b'\n' => f. write_str ( "\\ n" ) ?,
88- b'\r' => f. write_str ( "\\ r" ) ?,
89- // String escape characters.
90- b'\"' => f. write_str ( "\\ \" " ) ?,
91- b'\\' => f. write_str ( "\\ \\ " ) ?,
92- // Printable characters.
93- 0x20 ..=0x7e => f. write_char ( b as char ) ?,
94- _ => write ! ( f, "\\ x{:02x}" , b) ?,
95- }
96- }
97- f. write_char ( '"' )
98- }
99- }
100-
101- impl Deref for BStr {
102- type Target = [ u8 ] ;
103-
104- #[ inline]
105- fn deref ( & self ) -> & Self :: Target {
106- & self . 0
107- }
108- }
13+ ///
14+ /// `BStr` is simply an alias to `[u8]`, but has a more evident semantical meaning.
15+ pub type BStr = [ u8 ] ;
10916
11017/// Creates a new [`BStr`] from a string literal.
11118///
@@ -123,7 +30,7 @@ impl Deref for BStr {
12330macro_rules! b_str {
12431 ( $str: literal) => { {
12532 const S : & ' static str = $str;
126- const C : & ' static $crate:: str :: BStr = $crate :: str :: BStr :: from_bytes ( S . as_bytes( ) ) ;
33+ const C : & ' static $crate:: str :: BStr = S . as_bytes( ) ;
12734 C
12835 } } ;
12936}
@@ -438,7 +345,7 @@ impl fmt::Debug for CStr {
438345impl AsRef < BStr > for CStr {
439346 #[ inline]
440347 fn as_ref ( & self ) -> & BStr {
441- BStr :: from_bytes ( self . as_bytes ( ) )
348+ self . as_bytes ( )
442349 }
443350}
444351
@@ -447,7 +354,7 @@ impl Deref for CStr {
447354
448355 #[ inline]
449356 fn deref ( & self ) -> & Self :: Target {
450- self . as_ref ( )
357+ self . as_bytes ( )
451358 }
452359}
453360
@@ -494,7 +401,7 @@ where
494401
495402 #[ inline]
496403 fn index ( & self , index : Idx ) -> & Self :: Output {
497- & self . as_ref ( ) [ index]
404+ & self . as_bytes ( ) [ index]
498405 }
499406}
500407
@@ -524,21 +431,6 @@ macro_rules! c_str {
524431#[ cfg( test) ]
525432mod tests {
526433 use super :: * ;
527- use alloc:: format;
528-
529- const ALL_ASCII_CHARS : & ' static str =
530- "\\ x01\\ x02\\ x03\\ x04\\ x05\\ x06\\ x07\\ x08\\ x09\\ x0a\\ x0b\\ x0c\\ x0d\\ x0e\\ x0f\
531- \\ x10\\ x11\\ x12\\ x13\\ x14\\ x15\\ x16\\ x17\\ x18\\ x19\\ x1a\\ x1b\\ x1c\\ x1d\\ x1e\\ x1f \
532- !\" #$%&'()*+,-./0123456789:;<=>?@\
533- ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\ ]^_`abcdefghijklmnopqrstuvwxyz{|}~\\ x7f\
534- \\ x80\\ x81\\ x82\\ x83\\ x84\\ x85\\ x86\\ x87\\ x88\\ x89\\ x8a\\ x8b\\ x8c\\ x8d\\ x8e\\ x8f\
535- \\ x90\\ x91\\ x92\\ x93\\ x94\\ x95\\ x96\\ x97\\ x98\\ x99\\ x9a\\ x9b\\ x9c\\ x9d\\ x9e\\ x9f\
536- \\ xa0\\ xa1\\ xa2\\ xa3\\ xa4\\ xa5\\ xa6\\ xa7\\ xa8\\ xa9\\ xaa\\ xab\\ xac\\ xad\\ xae\\ xaf\
537- \\ xb0\\ xb1\\ xb2\\ xb3\\ xb4\\ xb5\\ xb6\\ xb7\\ xb8\\ xb9\\ xba\\ xbb\\ xbc\\ xbd\\ xbe\\ xbf\
538- \\ xc0\\ xc1\\ xc2\\ xc3\\ xc4\\ xc5\\ xc6\\ xc7\\ xc8\\ xc9\\ xca\\ xcb\\ xcc\\ xcd\\ xce\\ xcf\
539- \\ xd0\\ xd1\\ xd2\\ xd3\\ xd4\\ xd5\\ xd6\\ xd7\\ xd8\\ xd9\\ xda\\ xdb\\ xdc\\ xdd\\ xde\\ xdf\
540- \\ xe0\\ xe1\\ xe2\\ xe3\\ xe4\\ xe5\\ xe6\\ xe7\\ xe8\\ xe9\\ xea\\ xeb\\ xec\\ xed\\ xee\\ xef\
541- \\ xf0\\ xf1\\ xf2\\ xf3\\ xf4\\ xf5\\ xf6\\ xf7\\ xf8\\ xf9\\ xfa\\ xfb\\ xfc\\ xfd\\ xfe\\ xff";
542434
543435 #[ test]
544436 fn test_cstr_to_str ( ) {
@@ -563,69 +455,6 @@ mod tests {
563455 let unchecked_str = unsafe { checked_cstr. as_str_unchecked ( ) } ;
564456 assert_eq ! ( unchecked_str, "🐧" ) ;
565457 }
566-
567- #[ test]
568- fn test_cstr_display ( ) {
569- let hello_world = CStr :: from_bytes_with_nul ( b"hello, world!\0 " ) . unwrap ( ) ;
570- assert_eq ! ( format!( "{}" , hello_world) , "hello, world!" ) ;
571- let non_printables = CStr :: from_bytes_with_nul ( b"\x01 \x09 \x0a \0 " ) . unwrap ( ) ;
572- assert_eq ! ( format!( "{}" , non_printables) , "\\ x01\\ x09\\ x0a" ) ;
573- let non_ascii = CStr :: from_bytes_with_nul ( b"d\xe9 j\xe0 vu\0 " ) . unwrap ( ) ;
574- assert_eq ! ( format!( "{}" , non_ascii) , "d\\ xe9j\\ xe0 vu" ) ;
575- let good_bytes = CStr :: from_bytes_with_nul ( b"\xf0 \x9f \xa6 \x80 \0 " ) . unwrap ( ) ;
576- assert_eq ! ( format!( "{}" , good_bytes) , "\\ xf0\\ x9f\\ xa6\\ x80" ) ;
577- }
578-
579- #[ test]
580- fn test_cstr_display_all_bytes ( ) {
581- let mut bytes: [ u8 ; 256 ] = [ 0 ; 256 ] ;
582- // fill `bytes` with [1..=255] + [0]
583- for i in u8:: MIN ..=u8:: MAX {
584- bytes[ i as usize ] = i. wrapping_add ( 1 ) ;
585- }
586- let cstr = CStr :: from_bytes_with_nul ( & bytes) . unwrap ( ) ;
587- assert_eq ! ( format!( "{}" , cstr) , ALL_ASCII_CHARS ) ;
588- }
589-
590- #[ test]
591- fn test_cstr_debug ( ) {
592- let hello_world = CStr :: from_bytes_with_nul ( b"hello, world!\0 " ) . unwrap ( ) ;
593- assert_eq ! ( format!( "{:?}" , hello_world) , "\" hello, world!\" " ) ;
594- let non_printables = CStr :: from_bytes_with_nul ( b"\x01 \x09 \x0a \0 " ) . unwrap ( ) ;
595- assert_eq ! ( format!( "{:?}" , non_printables) , "\" \\ x01\\ x09\\ x0a\" " ) ;
596- let non_ascii = CStr :: from_bytes_with_nul ( b"d\xe9 j\xe0 vu\0 " ) . unwrap ( ) ;
597- assert_eq ! ( format!( "{:?}" , non_ascii) , "\" d\\ xe9j\\ xe0 vu\" " ) ;
598- let good_bytes = CStr :: from_bytes_with_nul ( b"\xf0 \x9f \xa6 \x80 \0 " ) . unwrap ( ) ;
599- assert_eq ! ( format!( "{:?}" , good_bytes) , "\" \\ xf0\\ x9f\\ xa6\\ x80\" " ) ;
600- }
601-
602- #[ test]
603- fn test_bstr_display ( ) {
604- let hello_world = BStr :: from_bytes ( b"hello, world!" ) ;
605- assert_eq ! ( format!( "{}" , hello_world) , "hello, world!" ) ;
606- let escapes = BStr :: from_bytes ( b"_\t _\n _\r _\\ _\' _\" _" ) ;
607- assert_eq ! ( format!( "{}" , escapes) , "_\\ t_\\ n_\\ r_\\ _'_\" _" ) ;
608- let others = BStr :: from_bytes ( b"\x01 " ) ;
609- assert_eq ! ( format!( "{}" , others) , "\\ x01" ) ;
610- let non_ascii = BStr :: from_bytes ( b"d\xe9 j\xe0 vu" ) ;
611- assert_eq ! ( format!( "{}" , non_ascii) , "d\\ xe9j\\ xe0 vu" ) ;
612- let good_bytes = BStr :: from_bytes ( b"\xf0 \x9f \xa6 \x80 " ) ;
613- assert_eq ! ( format!( "{}" , good_bytes) , "\\ xf0\\ x9f\\ xa6\\ x80" ) ;
614- }
615-
616- #[ test]
617- fn test_bstr_debug ( ) {
618- let hello_world = BStr :: from_bytes ( b"hello, world!" ) ;
619- assert_eq ! ( format!( "{:?}" , hello_world) , "\" hello, world!\" " ) ;
620- let escapes = BStr :: from_bytes ( b"_\t _\n _\r _\\ _\' _\" _" ) ;
621- assert_eq ! ( format!( "{:?}" , escapes) , "\" _\\ t_\\ n_\\ r_\\ \\ _'_\\ \" _\" " ) ;
622- let others = BStr :: from_bytes ( b"\x01 " ) ;
623- assert_eq ! ( format!( "{:?}" , others) , "\" \\ x01\" " ) ;
624- let non_ascii = BStr :: from_bytes ( b"d\xe9 j\xe0 vu" ) ;
625- assert_eq ! ( format!( "{:?}" , non_ascii) , "\" d\\ xe9j\\ xe0 vu\" " ) ;
626- let good_bytes = BStr :: from_bytes ( b"\xf0 \x9f \xa6 \x80 " ) ;
627- assert_eq ! ( format!( "{:?}" , good_bytes) , "\" \\ xf0\\ x9f\\ xa6\\ x80\" " ) ;
628- }
629458}
630459
631460/// Allows formatting of [`fmt::Arguments`] into a raw buffer.
0 commit comments