66// cSpell:ignore strs
77
88use clap:: { Arg , ArgAction , Command , builder:: ValueParser } ;
9- use std:: error:: Error ;
109use std:: ffi:: OsString ;
1110use std:: io:: { self , Write } ;
1211use uucore:: error:: { UResult , USimpleError , strip_errno} ;
1312use uucore:: format_usage;
1413use 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
1816const BUF_SIZE : usize = 16 * 1024 ;
1917
2018#[ uucore:: main]
2119pub 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
9491fn 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