Skip to content

Commit 29cac46

Browse files
committed
date: move raw format bytes into Format::Custom enum variant
1 parent 8926e4b commit 29cac46

1 file changed

Lines changed: 17 additions & 11 deletions

File tree

src/uu/date/src/date.rs

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,6 @@ const UNICODE_REPLACEMENT: char = '\u{FFFD}';
6060
struct Settings {
6161
utc: bool,
6262
format: Format,
63-
/// Raw format bytes for Custom format, to preserve non-UTF-8 bytes in output
64-
format_raw: Option<Vec<u8>>,
6563
date_source: DateSource,
6664
set_to: Option<Zoned>,
6765
debug: bool,
@@ -91,7 +89,11 @@ enum Format {
9189
Rfc5322,
9290
Rfc3339(Rfc3339Format),
9391
Resolution,
94-
Custom(String),
92+
/// A user-supplied format string (after stripping the leading `+`).
93+
/// The `String` is a lossy-UTF-8 copy used by strftime; the optional
94+
/// `Vec<u8>` holds the original bytes when they contained non-UTF-8
95+
/// sequences, so that those bytes can be restored in the output.
96+
Custom(String, Option<Vec<u8>>),
9597
Default,
9698
}
9799

@@ -323,7 +325,6 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
323325
}
324326
}
325327

326-
let mut format_raw: Option<Vec<u8>> = None;
327328
let format = if let Some(form) = matches.get_one::<OsString>(OPT_FORMAT) {
328329
let raw_bytes = form.as_encoded_bytes();
329330
if raw_bytes.first() != Some(&b'+') {
@@ -344,11 +345,13 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
344345
));
345346
}
346347
let bytes_after_plus = &raw_bytes[1..];
347-
if std::str::from_utf8(bytes_after_plus).is_err() {
348-
format_raw = Some(bytes_after_plus.to_vec());
349-
}
348+
let format_raw = if std::str::from_utf8(bytes_after_plus).is_err() {
349+
Some(bytes_after_plus.to_vec())
350+
} else {
351+
None
352+
};
350353
let form = String::from_utf8_lossy(bytes_after_plus).into_owned();
351-
Format::Custom(form)
354+
Format::Custom(form, format_raw)
352355
} else if let Some(fmt) = matches
353356
.get_many::<String>(OPT_ISO_8601)
354357
.map(|mut iter| iter.next().unwrap_or(&DATE.to_string()).as_str().into())
@@ -394,7 +397,6 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
394397
let settings = Settings {
395398
utc,
396399
format,
397-
format_raw,
398400
date_source,
399401
set_to,
400402
debug: debug_mode,
@@ -561,7 +563,11 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
561563
// Pre-extract non-UTF-8 chunks from the raw format bytes (if any).
562564
// from_utf8_lossy emits one U+FFFD per ill-formed subsequence (WTF-8 spec),
563565
// so we can match them 1:1 when restoring original bytes in the output.
564-
let raw_chunks: Option<Vec<&[u8]>> = settings.format_raw.as_ref().map(|raw| {
566+
let format_raw_ref = match &settings.format {
567+
Format::Custom(_, Some(raw)) => Some(raw),
568+
_ => None,
569+
};
570+
let raw_chunks: Option<Vec<&[u8]>> = format_raw_ref.map(|raw| {
565571
let mut chunks = Vec::new();
566572
let mut i = 0;
567573
while i < raw.len() {
@@ -812,7 +818,7 @@ fn make_format_string(settings: &Settings) -> &str {
812818
Rfc3339Format::Ns => "%F %T.%N%:z",
813819
},
814820
Format::Resolution => "%s.%N",
815-
Format::Custom(ref fmt) => fmt,
821+
Format::Custom(ref fmt, _) => fmt,
816822
Format::Default => locale::get_locale_default_format(),
817823
}
818824
}

0 commit comments

Comments
 (0)