Skip to content

Commit 0ecd274

Browse files
committed
update path type
Use PathBuf/Path instead of String for internal APIs
1 parent 3081231 commit 0ecd274

File tree

3 files changed

+44
-34
lines changed

3 files changed

+44
-34
lines changed

macros/src/parser.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,14 @@ impl<I: Iterator<Item = ParseArg>> Parser<I> {
8888
ParseRedirectFile(fd1, file, append) => {
8989
let mut redirect = quote!(::cmd_lib::Redirect);
9090
match fd1 {
91-
0 => redirect.extend(quote!(::FileToStdin(#file))),
92-
1 => redirect.extend(quote!(::StdoutToFile(#file, #append))),
93-
2 => redirect.extend(quote!(::StderrToFile(#file, #append))),
91+
0 => redirect
92+
.extend(quote!(::FileToStdin(::std::path::PathBuf::from(#file)))),
93+
1 => redirect.extend(
94+
quote!(::StdoutToFile(::std::path::PathBuf::from(#file), #append)),
95+
),
96+
2 => redirect.extend(
97+
quote!(::StderrToFile(::std::path::PathBuf::from(#file), #append)),
98+
),
9499
_ => panic!("unsupported fd ({}) redirect to file {}", fd1, file),
95100
}
96101
ret.extend(quote!(.add_redirect(#redirect)));

src/builtins.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use crate::{CmdEnv, CmdResult};
22
use log::*;
33
use std::io::{Read, Write};
4+
use std::path::PathBuf;
45

56
#[doc(hidden)]
67
pub fn builtin_true(_env: &mut CmdEnv) -> CmdResult {
@@ -58,9 +59,9 @@ pub fn builtin_cat(env: &mut CmdEnv) -> CmdResult {
5859
return Ok(());
5960
}
6061

61-
let mut file = env.args()[1].clone();
62-
if !file.starts_with('/') && !env.current_dir().is_empty() {
63-
file = format!("{}/{}", env.current_dir(), file);
62+
let mut file = PathBuf::from(env.args()[1].to_owned());
63+
if file.is_relative() {
64+
file = PathBuf::from(env.current_dir()).join(file);
6465
}
6566
env.stdout().write_all(&std::fs::read(file)?)?;
6667
Ok(())

src/process.rs

Lines changed: 32 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use std::collections::HashMap;
99
use std::fmt;
1010
use std::fs::{File, OpenOptions};
1111
use std::io::{Error, ErrorKind, Read, Result, Write};
12-
use std::path::Path;
12+
use std::path::{Path, PathBuf};
1313
use std::process::{Command, Stdio};
1414
use std::sync::Mutex;
1515

@@ -20,7 +20,7 @@ pub struct CmdEnv {
2020
stderr: CmdOut,
2121
args: Vec<String>,
2222
vars: HashMap<String, String>,
23-
current_dir: String,
23+
current_dir: PathBuf,
2424
}
2525
impl CmdEnv {
2626
/// Returns the arguments for this command
@@ -34,7 +34,7 @@ impl CmdEnv {
3434
}
3535

3636
/// Returns the current working directory for this command
37-
pub fn current_dir(&self) -> &str {
37+
pub fn current_dir(&self) -> &Path {
3838
&self.current_dir
3939
}
4040

@@ -88,7 +88,7 @@ pub fn set_pipefail(enable: bool) {
8888
#[derive(Default)]
8989
pub struct GroupCmds {
9090
group_cmds: Vec<(Cmds, Option<Cmds>)>, // (cmd, orCmd) pairs
91-
current_dir: String,
91+
current_dir: PathBuf,
9292
}
9393

9494
impl GroupCmds {
@@ -169,7 +169,7 @@ impl Cmds {
169169
&self.full_cmds
170170
}
171171

172-
fn spawn(&mut self, current_dir: &mut String) -> Result<CmdChildren> {
172+
fn spawn(&mut self, current_dir: &mut PathBuf) -> Result<CmdChildren> {
173173
if std::env::var("CMD_LIB_DEBUG") == Ok("1".into()) {
174174
debug!("Running {} ...", self.get_full_cmds());
175175
}
@@ -195,41 +195,41 @@ impl Cmds {
195195
Ok(CmdChildren::from(children))
196196
}
197197

198-
fn run_cmd(&mut self, current_dir: &mut String) -> CmdResult {
198+
fn run_cmd(&mut self, current_dir: &mut PathBuf) -> CmdResult {
199199
self.spawn(current_dir)?.wait_cmd_result_nolog()
200200
}
201201

202-
fn run_fun(&mut self, current_dir: &mut String) -> FunResult {
202+
fn run_fun(&mut self, current_dir: &mut PathBuf) -> FunResult {
203203
self.spawn(current_dir)?.wait_fun_result_nolog()
204204
}
205205
}
206206

207207
#[doc(hidden)]
208208
pub enum Redirect {
209-
FileToStdin(String),
209+
FileToStdin(PathBuf),
210210
StdoutToStderr,
211211
StderrToStdout,
212-
StdoutToFile(String, bool),
213-
StderrToFile(String, bool),
212+
StdoutToFile(PathBuf, bool),
213+
StderrToFile(PathBuf, bool),
214214
}
215215
impl fmt::Debug for Redirect {
216216
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
217217
match self {
218-
Redirect::FileToStdin(path) => f.write_str(&format!("< {}", path)),
218+
Redirect::FileToStdin(path) => f.write_str(&format!("< {}", path.display())),
219219
Redirect::StdoutToStderr => f.write_str(">&2"),
220220
Redirect::StderrToStdout => f.write_str("2>&1"),
221221
Redirect::StdoutToFile(path, append) => {
222222
if *append {
223-
f.write_str(&format!("1>> {}", path))
223+
f.write_str(&format!("1>> {}", path.display()))
224224
} else {
225-
f.write_str(&format!("1> {}", path))
225+
f.write_str(&format!("1> {}", path.display()))
226226
}
227227
}
228228
Redirect::StderrToFile(path, append) => {
229229
if *append {
230-
f.write_str(&format!("2>> {}", path))
230+
f.write_str(&format!("2>> {}", path.display()))
231231
} else {
232-
f.write_str(&format!("2> {}", path))
232+
f.write_str(&format!("2> {}", path.display()))
233233
}
234234
}
235235
}
@@ -335,7 +335,7 @@ impl Cmd {
335335
self
336336
}
337337

338-
fn spawn(mut self, current_dir: &mut String) -> Result<CmdChild> {
338+
fn spawn(mut self, current_dir: &mut PathBuf) -> Result<CmdChild> {
339339
let arg0 = self.arg0();
340340
let full_cmd = self.debug_str();
341341
if arg0 == "cd" {
@@ -350,7 +350,11 @@ impl Cmd {
350350
let mut env = CmdEnv {
351351
args: self.args,
352352
vars: self.vars,
353-
current_dir: current_dir.clone(),
353+
current_dir: if current_dir.as_os_str().is_empty() {
354+
std::env::current_dir()?
355+
} else {
356+
current_dir.clone()
357+
},
354358
stdin: if let Some(redirect_in) = self.stdin_redirect.take() {
355359
redirect_in
356360
} else {
@@ -390,7 +394,7 @@ impl Cmd {
390394
let mut cmd = self.std_cmd.take().unwrap();
391395

392396
// setup current_dir
393-
if !current_dir.is_empty() {
397+
if !current_dir.as_os_str().is_empty() {
394398
cmd.current_dir(current_dir.clone());
395399
}
396400

@@ -421,7 +425,7 @@ impl Cmd {
421425
}
422426
}
423427

424-
fn run_cd_cmd(&self, current_dir: &mut String) -> CmdResult {
428+
fn run_cd_cmd(&self, current_dir: &mut PathBuf) -> CmdResult {
425429
if self.args.len() == 1 {
426430
return Err(Error::new(ErrorKind::Other, "cd: missing directory"));
427431
} else if self.args.len() > 2 {
@@ -441,11 +445,11 @@ impl Cmd {
441445
return Err(e);
442446
}
443447

444-
*current_dir = dir.clone();
448+
*current_dir = PathBuf::from(dir);
445449
Ok(())
446450
}
447451

448-
fn open_file(path: &str, read_only: bool, append: bool) -> Result<File> {
452+
fn open_file(path: &Path, read_only: bool, append: bool) -> Result<File> {
449453
if read_only {
450454
OpenOptions::new().read(true).open(path)
451455
} else {
@@ -484,7 +488,7 @@ impl Cmd {
484488
for redirect in self.redirects.iter() {
485489
match redirect {
486490
Redirect::FileToStdin(path) => {
487-
self.stdin_redirect = Some(if path == "/dev/null" {
491+
self.stdin_redirect = Some(if path == Path::new("/dev/null") {
488492
CmdIn::CmdNull
489493
} else {
490494
CmdIn::CmdFile(Self::open_file(path, true, false)?)
@@ -505,14 +509,14 @@ impl Cmd {
505509
}
506510
}
507511
Redirect::StdoutToFile(path, append) => {
508-
self.stdout_redirect = Some(if path == "/dev/null" {
512+
self.stdout_redirect = Some(if path == Path::new("/dev/null") {
509513
CmdOut::CmdNull
510514
} else {
511515
CmdOut::CmdFile(Self::open_file(path, false, *append)?)
512516
});
513517
}
514518
Redirect::StderrToFile(path, append) => {
515-
self.stderr_redirect = Some(if path == "/dev/null" {
519+
self.stderr_redirect = Some(if path == Path::new("/dev/null") {
516520
CmdOut::CmdNull
517521
} else {
518522
CmdOut::CmdFile(Self::open_file(path, false, *append)?)
@@ -530,7 +534,7 @@ mod tests {
530534

531535
#[test]
532536
fn test_run_piped_cmds() {
533-
let mut current_dir = String::new();
537+
let mut current_dir = PathBuf::new();
534538
assert!(Cmds::default()
535539
.pipe(Cmd::default().add_args(vec!["echo".into(), "rust".into()]))
536540
.pipe(Cmd::default().add_args(vec!["wc".into()]))
@@ -540,7 +544,7 @@ mod tests {
540544

541545
#[test]
542546
fn test_run_piped_funs() {
543-
let mut current_dir = String::new();
547+
let mut current_dir = PathBuf::new();
544548
assert_eq!(
545549
Cmds::default()
546550
.pipe(Cmd::default().add_args(vec!["echo".into(), "rust".into()]))
@@ -562,10 +566,10 @@ mod tests {
562566

563567
#[test]
564568
fn test_stdout_redirect() {
565-
let mut current_dir = String::new();
569+
let mut current_dir = PathBuf::new();
566570
let tmp_file = "/tmp/file_echo_rust";
567571
let mut write_cmd = Cmd::default().add_args(vec!["echo".into(), "rust".into()]);
568-
write_cmd = write_cmd.add_redirect(Redirect::StdoutToFile(tmp_file.to_string(), false));
572+
write_cmd = write_cmd.add_redirect(Redirect::StdoutToFile(PathBuf::from(tmp_file), false));
569573
assert!(Cmds::default()
570574
.pipe(write_cmd)
571575
.run_cmd(&mut current_dir)

0 commit comments

Comments
 (0)