Skip to content

Commit 33745a0

Browse files
oech3RenjiSann
authored andcommitted
yes: simplify logic for buffer creation
1 parent 8fc6e95 commit 33745a0

File tree

1 file changed

+16
-21
lines changed

1 file changed

+16
-21
lines changed

src/uu/yes/src/yes.rs

Lines changed: 16 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,24 +6,21 @@
66
// cSpell:ignore strs
77

88
use clap::{Arg, ArgAction, Command, builder::ValueParser};
9-
use std::error::Error;
109
use std::ffi::OsString;
1110
use std::io::{self, Write};
1211
use uucore::error::{UResult, USimpleError, strip_errno};
1312
use uucore::format_usage;
1413
use uucore::translate;
1514

16-
// it's possible that using a smaller or larger buffer might provide better performance on some
17-
// systems, but honestly this is good enough
15+
// it's possible that using a smaller or larger buffer might provide better performance
1816
const BUF_SIZE: usize = 16 * 1024;
1917

2018
#[uucore::main]
2119
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
2220
let matches = uucore::clap_localization::handle_clap_result(uu_app(), args)?;
2321

24-
let mut buffer = Vec::with_capacity(BUF_SIZE);
2522
#[allow(clippy::unwrap_used, reason = "clap provides 'y' by default")]
26-
let _ = args_into_buffer(&mut buffer, matches.get_many::<OsString>("STRING").unwrap());
23+
let mut buffer = args_into_buffer(matches.get_many::<OsString>("STRING").unwrap())?;
2724
prepare_buffer(&mut buffer);
2825

2926
match exec(&buffer) {
@@ -53,12 +50,10 @@ pub fn uu_app() -> Command {
5350
.infer_long_args(true)
5451
}
5552

56-
/// Copies words from `i` into `buf`, separated by spaces.
53+
/// create a buffer filled by words `i` separated by spaces.
5754
#[allow(clippy::unnecessary_wraps, reason = "needed on some platforms")]
58-
fn args_into_buffer<'a>(
59-
buf: &mut Vec<u8>,
60-
i: impl Iterator<Item = &'a OsString>,
61-
) -> Result<(), Box<dyn Error>> {
55+
fn args_into_buffer<'a>(i: impl Iterator<Item = &'a OsString>) -> UResult<Vec<u8>> {
56+
let mut buf = Vec::with_capacity(BUF_SIZE);
6257
// On Unix (and wasi), OsStrs are just &[u8]'s underneath...
6358
#[cfg(any(unix, target_os = "wasi"))]
6459
{
@@ -78,23 +73,25 @@ fn args_into_buffer<'a>(
7873
for part in itertools::intersperse(i.map(|a| a.to_str()), Some(" ")) {
7974
let bytes = match part {
8075
Some(part) => part.as_bytes(),
81-
None => return Err(translate!("yes-error-invalid-utf8").into()),
76+
None => {
77+
return Err(USimpleError::new(1, translate!("yes-error-invalid-utf8")));
78+
}
8279
};
8380
buf.extend_from_slice(bytes);
8481
}
8582
}
8683

8784
buf.push(b'\n');
8885

89-
Ok(())
86+
Ok(buf)
9087
}
9188

9289
/// Assumes buf holds a single output line forged from the command line arguments, copies it
93-
/// repeatedly until the buffer holds as many copies as it can under [`BUF_SIZE`].
90+
/// repeatedly until the buffer holds as many copies as it can
9491
fn prepare_buffer(buf: &mut Vec<u8>) {
9592
let line_len = buf.len();
9693
debug_assert!(line_len > 0, "buffer is not empty since we have newline");
97-
let target_size = line_len * (BUF_SIZE / line_len); // 0 if line_len is already large enough
94+
let target_size = line_len * (buf.capacity() / line_len); // 0 if line_len is already large enough
9895

9996
while buf.len() < target_size {
10097
let to_copy = std::cmp::min(target_size - buf.len(), buf.len());
@@ -137,7 +134,8 @@ mod tests {
137134
];
138135

139136
for (line, final_len) in tests {
140-
let mut v = std::iter::repeat_n(b'a', line).collect::<Vec<_>>();
137+
let mut v = Vec::with_capacity(BUF_SIZE);
138+
v.extend(std::iter::repeat_n(b'a', line));
141139
prepare_buffer(&mut v);
142140
assert_eq!(v.len(), final_len);
143141
}
@@ -146,23 +144,20 @@ mod tests {
146144
#[test]
147145
fn test_args_into_buf() {
148146
{
149-
let mut v = Vec::with_capacity(BUF_SIZE);
150147
let default_args = ["y".into()];
151-
args_into_buffer(&mut v, default_args.iter()).unwrap();
148+
let v = args_into_buffer(default_args.iter()).unwrap();
152149
assert_eq!(String::from_utf8(v).unwrap(), "y\n");
153150
}
154151

155152
{
156-
let mut v = Vec::with_capacity(BUF_SIZE);
157153
let args = ["foo".into()];
158-
args_into_buffer(&mut v, args.iter()).unwrap();
154+
let v = args_into_buffer(args.iter()).unwrap();
159155
assert_eq!(String::from_utf8(v).unwrap(), "foo\n");
160156
}
161157

162158
{
163-
let mut v = Vec::with_capacity(BUF_SIZE);
164159
let args = ["foo".into(), "bar baz".into(), "qux".into()];
165-
args_into_buffer(&mut v, args.iter()).unwrap();
160+
let v = args_into_buffer(args.iter()).unwrap();
166161
assert_eq!(String::from_utf8(v).unwrap(), "foo bar baz qux\n");
167162
}
168163
}

0 commit comments

Comments
 (0)