Skip to content

Commit 8ac2d2a

Browse files
committed
perf(tsort): avoid redundant check on input
1 parent 3cd87f8 commit 8ac2d2a

File tree

1 file changed

+32
-13
lines changed

1 file changed

+32
-13
lines changed

src/uu/tsort/src/tsort.rs

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,11 @@ use std::collections::{HashMap, VecDeque};
1010
use std::ffi::OsString;
1111
use std::fs::File;
1212
use std::io::{self, BufRead, BufReader};
13-
use std::path::Path;
1413
use string_interner::StringInterner;
1514
use string_interner::backend::StringBackend;
1615
use thiserror::Error;
1716
use uucore::display::Quotable;
18-
use uucore::error::{UError, UResult, USimpleError};
17+
use uucore::error::{UError, UIoError, UResult, USimpleError};
1918
use uucore::{format_usage, show, translate};
2019

2120
// short types for switching interning behavior on the fly.
@@ -60,14 +59,33 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
6059
if input == "-" {
6160
process_input(io::stdin().lock(), &mut g)?;
6261
} else {
62+
let file = open_file(input)?;
63+
64+
let reader = BufReader::new(file);
65+
process_input(reader, &mut g)?;
66+
}
67+
68+
g.run_tsort();
69+
Ok(())
70+
}
71+
72+
fn open_file(input: &OsString) -> Result<File, UIoError> {
73+
// Windows throws a permission denied error when trying to read a directory,
74+
// so we need to check manually beforehand.
75+
#[cfg(windows)]
76+
{
77+
use std::path::Path;
6378
let path = Path::new(&input);
6479
if path.is_dir() {
65-
return Err(TsortError::IsDir(input.to_string_lossy().to_string()).into());
80+
return Err(TsortError::IsDir(input.to_string_lossy().to_string()));
6681
}
6782

68-
let file = File::open(path)?;
69-
70-
// advise the OS we will access the data sequentially if available.
83+
Ok(File::open(path)?)
84+
}
85+
// advise the OS that we are going to read the file sequentially, if available.
86+
#[cfg(not(windows))]
87+
{
88+
let file = File::open(input)?;
7189
#[cfg(any(
7290
target_os = "linux",
7391
target_os = "android",
@@ -88,13 +106,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
88106
)
89107
.ok();
90108
}
91-
92-
let reader = BufReader::new(file);
93-
process_input(reader, &mut g)?;
109+
Ok(file)
94110
}
95-
96-
g.run_tsort();
97-
Ok(())
98111
}
99112

100113
pub fn uu_app() -> Command {
@@ -160,7 +173,13 @@ fn process_input<R: BufRead>(reader: R, graph: &mut Graph) -> Result<(), TsortEr
160173
// with tokens separated by whitespaces
161174

162175
for line in reader.lines() {
163-
let line = line?;
176+
let line = line.map_err(|e| {
177+
if e.kind() == io::ErrorKind::IsADirectory {
178+
TsortError::IsDir(graph.name())
179+
} else {
180+
e.into()
181+
}
182+
})?;
164183
for token in line.split_whitespace() {
165184
// Intern the token and get a Sym
166185
let token_sym = graph.interner.get_or_intern(token);

0 commit comments

Comments
 (0)