Skip to content

Commit f8a2c63

Browse files
authored
Merge pull request #547 from mbartlett21/patch-1
Implement `Display` and `Debug` for `CStr`
2 parents 8c64300 + 7c7a492 commit f8a2c63

File tree

1 file changed

+53
-0
lines changed

1 file changed

+53
-0
lines changed

rust/kernel/str.rs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
//! String representations.
44
5+
use core::fmt::{self, Write};
56
use core::ops::{self, Deref, Index};
67

78
use crate::bindings;
@@ -209,6 +210,58 @@ impl CStr {
209210
}
210211
}
211212

213+
impl fmt::Display for CStr {
214+
/// Formats printable ASCII characters, escaping the rest.
215+
///
216+
/// ```
217+
/// # use kernel::c_str;
218+
/// # use kernel::str::CStr;
219+
/// let penguin = c_str!("🐧");
220+
/// assert_eq!(format!("{}", penguin), "\\xf0\\x9f\\x90\\xa7");
221+
///
222+
/// let ascii = c_str!("so \"cool\"");
223+
/// assert_eq!(format!("{}", ascii), "so \"cool\"");
224+
/// ```
225+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
226+
for &c in self.as_bytes() {
227+
if (0x20..0x7f).contains(&c) {
228+
// Printable character
229+
f.write_char(c as char)?;
230+
} else {
231+
write!(f, "\\x{:02x}", c)?;
232+
}
233+
}
234+
Ok(())
235+
}
236+
}
237+
238+
impl fmt::Debug for CStr {
239+
/// Formats printable ASCII characters with a double quote on either end, escaping the rest.
240+
///
241+
/// ```
242+
/// # use kernel::c_str;
243+
/// # use kernel::str::CStr;
244+
/// let penguin = c_str!("🐧");
245+
/// assert_eq!(format!("{:?}", penguin), "\"\\xf0\\x9f\\x90\\xa7\"");
246+
///
247+
/// // embedded double quotes are escaped
248+
/// let ascii = c_str!("so \"cool\"");
249+
/// assert_eq!(format!("{:?}", ascii), "\"so \\\"cool\\\"\"");
250+
/// ```
251+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
252+
f.write_str("\"")?;
253+
for &c in self.as_bytes() {
254+
match c {
255+
// Printable characters
256+
b'\"' => f.write_str("\\\"")?,
257+
0x20..=0x7e => f.write_char(c as char)?,
258+
_ => write!(f, "\\x{:02x}", c)?,
259+
}
260+
}
261+
f.write_str("\"")
262+
}
263+
}
264+
212265
impl AsRef<BStr> for CStr {
213266
#[inline]
214267
fn as_ref(&self) -> &BStr {

0 commit comments

Comments
 (0)