summaryrefslogtreecommitdiffstats
path: root/vendor/cxx/src/lossy.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/cxx/src/lossy.rs')
-rw-r--r--vendor/cxx/src/lossy.rs67
1 files changed, 67 insertions, 0 deletions
diff --git a/vendor/cxx/src/lossy.rs b/vendor/cxx/src/lossy.rs
new file mode 100644
index 000000000..8ccf0f93b
--- /dev/null
+++ b/vendor/cxx/src/lossy.rs
@@ -0,0 +1,67 @@
+use core::char;
+use core::fmt::{self, Write as _};
+use core::str;
+
+pub fn display(mut bytes: &[u8], f: &mut fmt::Formatter) -> fmt::Result {
+ loop {
+ match str::from_utf8(bytes) {
+ Ok(valid) => return f.write_str(valid),
+ Err(utf8_error) => {
+ let valid_up_to = utf8_error.valid_up_to();
+ let valid = unsafe { str::from_utf8_unchecked(&bytes[..valid_up_to]) };
+ f.write_str(valid)?;
+ f.write_char(char::REPLACEMENT_CHARACTER)?;
+ if let Some(error_len) = utf8_error.error_len() {
+ bytes = &bytes[valid_up_to + error_len..];
+ } else {
+ return Ok(());
+ }
+ }
+ }
+ }
+}
+
+pub fn debug(mut bytes: &[u8], f: &mut fmt::Formatter) -> fmt::Result {
+ f.write_char('"')?;
+
+ while !bytes.is_empty() {
+ let from_utf8_result = str::from_utf8(bytes);
+ let valid = match from_utf8_result {
+ Ok(valid) => valid,
+ Err(utf8_error) => {
+ let valid_up_to = utf8_error.valid_up_to();
+ unsafe { str::from_utf8_unchecked(&bytes[..valid_up_to]) }
+ }
+ };
+
+ let mut written = 0;
+ for (i, ch) in valid.char_indices() {
+ let esc = ch.escape_debug();
+ if esc.len() != 1 && ch != '\'' {
+ f.write_str(&valid[written..i])?;
+ for ch in esc {
+ f.write_char(ch)?;
+ }
+ written = i + ch.len_utf8();
+ }
+ }
+ f.write_str(&valid[written..])?;
+
+ match from_utf8_result {
+ Ok(_valid) => break,
+ Err(utf8_error) => {
+ let end_of_broken = if let Some(error_len) = utf8_error.error_len() {
+ valid.len() + error_len
+ } else {
+ bytes.len()
+ };
+ for b in &bytes[valid.len()..end_of_broken] {
+ write!(f, "\\x{:02x}", b)?;
+ }
+ bytes = &bytes[end_of_broken..];
+ }
+ }
+ }
+
+ f.write_char('"')
+}