Skip to content

Commit 21f6952

Browse files
committed
shared: remove escaping and UTF-8 routines from shared module
With the error refactor, these are no longer used. Namely, while switching to structured errors, I took that opportunity to slim down errors so that we are not repeating parts of the input as often.
1 parent a50f679 commit 21f6952

File tree

10 files changed

+210
-222
lines changed

10 files changed

+210
-222
lines changed

crates/jiff-static/src/shared/util/escape.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,3 +122,4 @@ impl core::fmt::Debug for RepeatByte {
122122
Ok(())
123123
}
124124
}
125+
Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
// auto-generated by: jiff-cli generate shared
22

33
pub(crate) mod array_str;
4-
pub(crate) mod escape;
54
pub(crate) mod itime;
6-
pub(crate) mod utf8;

crates/jiff-static/src/shared/util/utf8.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,3 +89,4 @@ pub(crate) fn decode(bytes: &[u8]) -> Option<Result<char, Utf8Error>> {
8989
// yield at least one Unicode scalar value.
9090
Some(Ok(string.chars().next().unwrap()))
9191
}
92+

src/error/fmt/offset.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::{error, shared::util::escape};
1+
use crate::{error, util::escape};
22

33
#[derive(Clone, Debug)]
44
pub(crate) enum Error {

src/fmt/strtime/format.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ use crate::{
1212
util::{DecimalFormatter, FractionalFormatter},
1313
Write, WriteExt,
1414
},
15-
shared::util::utf8,
1615
tz::Offset,
16+
util::utf8,
1717
Error,
1818
};
1919

src/shared/util/escape.rs

Lines changed: 0 additions & 122 deletions
This file was deleted.

src/shared/util/mod.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,2 @@
11
pub(crate) mod array_str;
2-
pub(crate) mod escape;
32
pub(crate) mod itime;
4-
pub(crate) mod utf8;

src/shared/util/utf8.rs

Lines changed: 0 additions & 89 deletions
This file was deleted.

src/util/escape.rs

Lines changed: 116 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,119 @@ Provides convenience routines for escaping raw bytes.
44
This was copied from `regex-automata` with a few light edits.
55
*/
66

7-
// These were originally defined here, but they got moved to
8-
// shared since they're needed there. We re-export them here
9-
// because this is really where they should live, but they're
10-
// in shared because `jiff-tzdb-static` needs it.
11-
pub(crate) use crate::shared::util::escape::{Byte, Bytes, RepeatByte};
7+
use super::utf8;
8+
9+
/// Provides a convenient `Debug` implementation for a `u8`.
10+
///
11+
/// The `Debug` impl treats the byte as an ASCII, and emits a human
12+
/// readable representation of it. If the byte isn't ASCII, then it's
13+
/// emitted as a hex escape sequence.
14+
#[derive(Clone, Copy)]
15+
pub(crate) struct Byte(pub u8);
16+
17+
impl core::fmt::Display for Byte {
18+
#[inline(never)]
19+
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
20+
if self.0 == b' ' {
21+
return write!(f, " ");
22+
}
23+
// 10 bytes is enough for any output from ascii::escape_default.
24+
let mut bytes = [0u8; 10];
25+
let mut len = 0;
26+
for (i, mut b) in core::ascii::escape_default(self.0).enumerate() {
27+
// capitalize \xab to \xAB
28+
if i >= 2 && b'a' <= b && b <= b'f' {
29+
b -= 32;
30+
}
31+
bytes[len] = b;
32+
len += 1;
33+
}
34+
write!(f, "{}", core::str::from_utf8(&bytes[..len]).unwrap())
35+
}
36+
}
37+
38+
impl core::fmt::Debug for Byte {
39+
#[inline(never)]
40+
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
41+
write!(f, "\"")?;
42+
core::fmt::Display::fmt(self, f)?;
43+
write!(f, "\"")?;
44+
Ok(())
45+
}
46+
}
47+
48+
/// Provides a convenient `Debug` implementation for `&[u8]`.
49+
///
50+
/// This generally works best when the bytes are presumed to be mostly
51+
/// UTF-8, but will work for anything. For any bytes that aren't UTF-8,
52+
/// they are emitted as hex escape sequences.
53+
#[derive(Clone, Copy)]
54+
pub(crate) struct Bytes<'a>(pub &'a [u8]);
55+
56+
impl<'a> core::fmt::Display for Bytes<'a> {
57+
#[inline(never)]
58+
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
59+
// This is a sad re-implementation of a similar impl found in bstr.
60+
let mut bytes = self.0;
61+
while let Some(result) = utf8::decode(bytes) {
62+
let ch = match result {
63+
Ok(ch) => ch,
64+
Err(err) => {
65+
// The decode API guarantees `errant_bytes` is non-empty.
66+
write!(f, r"\x{:02x}", err.as_slice()[0])?;
67+
bytes = &bytes[1..];
68+
continue;
69+
}
70+
};
71+
bytes = &bytes[ch.len_utf8()..];
72+
match ch {
73+
'\0' => write!(f, "\\0")?,
74+
'\x01'..='\x7f' => {
75+
write!(f, "{}", (ch as u8).escape_ascii())?;
76+
}
77+
_ => write!(f, "{}", ch.escape_debug())?,
78+
}
79+
}
80+
Ok(())
81+
}
82+
}
83+
84+
impl<'a> core::fmt::Debug for Bytes<'a> {
85+
#[inline(never)]
86+
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
87+
write!(f, "\"")?;
88+
core::fmt::Display::fmt(self, f)?;
89+
write!(f, "\"")?;
90+
Ok(())
91+
}
92+
}
93+
94+
/// A helper for repeating a single byte utilizing `Byte`.
95+
///
96+
/// This is limited to repeating a byte up to `u8::MAX` times in order
97+
/// to reduce its size overhead. And in practice, Jiff just doesn't
98+
/// need more than this (at time of writing, 2025-11-29).
99+
pub(crate) struct RepeatByte {
100+
pub(crate) byte: u8,
101+
pub(crate) count: u8,
102+
}
103+
104+
impl core::fmt::Display for RepeatByte {
105+
#[inline(never)]
106+
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
107+
for _ in 0..self.count {
108+
write!(f, "{}", Byte(self.byte))?;
109+
}
110+
Ok(())
111+
}
112+
}
113+
114+
impl core::fmt::Debug for RepeatByte {
115+
#[inline(never)]
116+
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
117+
write!(f, "\"")?;
118+
core::fmt::Display::fmt(self, f)?;
119+
write!(f, "\"")?;
120+
Ok(())
121+
}
122+
}

0 commit comments

Comments
 (0)