mirror of
https://github.com/BurntSushi/ripgrep.git
synced 2025-05-19 09:40:22 -07:00
ignore: polish
Like previous commits, we do a bit of polishing and bring the style up to my current practice.
This commit is contained in:
parent
be9e308999
commit
f16ea0812d
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -239,6 +239,7 @@ dependencies = [
|
|||||||
name = "ignore"
|
name = "ignore"
|
||||||
version = "0.4.20"
|
version = "0.4.20"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"bstr",
|
||||||
"crossbeam-channel",
|
"crossbeam-channel",
|
||||||
"crossbeam-deque",
|
"crossbeam-deque",
|
||||||
"globset",
|
"globset",
|
||||||
|
@ -42,5 +42,7 @@ serde_json = "1.0.107"
|
|||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["log"]
|
default = ["log"]
|
||||||
|
# DEPRECATED. It is a no-op. SIMD is done automatically through runtime
|
||||||
|
# dispatch.
|
||||||
simd-accel = []
|
simd-accel = []
|
||||||
serde1 = ["serde"]
|
serde1 = ["serde"]
|
||||||
|
@ -12,7 +12,7 @@ repository = "https://github.com/BurntSushi/ripgrep/tree/master/crates/ignore"
|
|||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
keywords = ["glob", "ignore", "gitignore", "pattern", "file"]
|
keywords = ["glob", "ignore", "gitignore", "pattern", "file"]
|
||||||
license = "Unlicense OR MIT"
|
license = "Unlicense OR MIT"
|
||||||
edition = "2018"
|
edition = "2021"
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
name = "ignore"
|
name = "ignore"
|
||||||
@ -22,18 +22,21 @@ bench = false
|
|||||||
crossbeam-deque = "0.8.3"
|
crossbeam-deque = "0.8.3"
|
||||||
globset = { version = "0.4.10", path = "../globset" }
|
globset = { version = "0.4.10", path = "../globset" }
|
||||||
lazy_static = "1.1"
|
lazy_static = "1.1"
|
||||||
log = "0.4.5"
|
log = "0.4.20"
|
||||||
memchr = "2.5"
|
memchr = "2.6.3"
|
||||||
regex = { version = "1.9.0", default-features = false, features = ["perf", "std", "unicode-gencat"] }
|
regex = { version = "1.9.5", default-features = false, features = ["perf", "std", "unicode-gencat"] }
|
||||||
same-file = "1.0.4"
|
same-file = "1.0.6"
|
||||||
thread_local = "1"
|
thread_local = "1"
|
||||||
walkdir = "2.2.7"
|
walkdir = "2.4.0"
|
||||||
|
|
||||||
[target.'cfg(windows)'.dependencies.winapi-util]
|
[target.'cfg(windows)'.dependencies.winapi-util]
|
||||||
version = "0.1.2"
|
version = "0.1.2"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
crossbeam-channel = "0.5.0"
|
bstr = { version = "1.6.2", default-features = false, features = ["std"] }
|
||||||
|
crossbeam-channel = "0.5.8"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
simd-accel = ["globset/simd-accel"]
|
# DEPRECATED. It is a no-op. SIMD is done automatically through runtime
|
||||||
|
# dispatch.
|
||||||
|
simd-accel = []
|
||||||
|
@ -1,10 +1,6 @@
|
|||||||
use std::env;
|
use std::{env, io::Write, path::Path};
|
||||||
use std::io::{self, Write};
|
|
||||||
use std::path::Path;
|
|
||||||
use std::thread;
|
|
||||||
|
|
||||||
use ignore::WalkBuilder;
|
use {bstr::ByteVec, ignore::WalkBuilder, walkdir::WalkDir};
|
||||||
use walkdir::WalkDir;
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut path = env::args().nth(1).unwrap();
|
let mut path = env::args().nth(1).unwrap();
|
||||||
@ -19,10 +15,11 @@ fn main() {
|
|||||||
simple = true;
|
simple = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
let stdout_thread = thread::spawn(move || {
|
let stdout_thread = std::thread::spawn(move || {
|
||||||
let mut stdout = io::BufWriter::new(io::stdout());
|
let mut stdout = std::io::BufWriter::new(std::io::stdout());
|
||||||
for dent in rx {
|
for dent in rx {
|
||||||
write_path(&mut stdout, dent.path());
|
stdout.write(&*Vec::from_path_lossy(dent.path())).unwrap();
|
||||||
|
stdout.write(b"\n").unwrap();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -65,16 +62,3 @@ impl DirEntry {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(unix)]
|
|
||||||
fn write_path<W: Write>(mut wtr: W, path: &Path) {
|
|
||||||
use std::os::unix::ffi::OsStrExt;
|
|
||||||
wtr.write(path.as_os_str().as_bytes()).unwrap();
|
|
||||||
wtr.write(b"\n").unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(unix))]
|
|
||||||
fn write_path<W: Write>(mut wtr: W, path: &Path) {
|
|
||||||
wtr.write(path.to_string_lossy().as_bytes()).unwrap();
|
|
||||||
wtr.write(b"\n").unwrap();
|
|
||||||
}
|
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
/// Please try to keep this list sorted lexicographically and wrapped to 79
|
/// Please try to keep this list sorted lexicographically and wrapped to 79
|
||||||
/// columns (inclusive).
|
/// columns (inclusive).
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
pub const DEFAULT_TYPES: &[(&[&str], &[&str])] = &[
|
pub(crate) const DEFAULT_TYPES: &[(&[&str], &[&str])] = &[
|
||||||
(&["ada"], &["*.adb", "*.ads"]),
|
(&["ada"], &["*.adb", "*.ads"]),
|
||||||
(&["agda"], &["*.agda", "*.lagda"]),
|
(&["agda"], &["*.agda", "*.lagda"]),
|
||||||
(&["aidl"], &["*.aidl"]),
|
(&["aidl"], &["*.aidl"]),
|
||||||
|
@ -13,24 +13,28 @@
|
|||||||
// with non-obvious failure modes. Alas, such things haven't been documented
|
// with non-obvious failure modes. Alas, such things haven't been documented
|
||||||
// well.
|
// well.
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::{
|
||||||
use std::ffi::{OsStr, OsString};
|
collections::HashMap,
|
||||||
use std::fs::{File, FileType};
|
ffi::{OsStr, OsString},
|
||||||
use std::io::{self, BufRead};
|
fs::{File, FileType},
|
||||||
use std::path::{Path, PathBuf};
|
io::{self, BufRead},
|
||||||
use std::sync::{Arc, RwLock};
|
path::{Path, PathBuf},
|
||||||
|
sync::{Arc, RwLock},
|
||||||
|
};
|
||||||
|
|
||||||
use crate::gitignore::{self, Gitignore, GitignoreBuilder};
|
use crate::{
|
||||||
use crate::overrides::{self, Override};
|
gitignore::{self, Gitignore, GitignoreBuilder},
|
||||||
use crate::pathutil::{is_hidden, strip_prefix};
|
overrides::{self, Override},
|
||||||
use crate::types::{self, Types};
|
pathutil::{is_hidden, strip_prefix},
|
||||||
use crate::walk::DirEntry;
|
types::{self, Types},
|
||||||
use crate::{Error, Match, PartialErrorBuilder};
|
walk::DirEntry,
|
||||||
|
{Error, Match, PartialErrorBuilder},
|
||||||
|
};
|
||||||
|
|
||||||
/// IgnoreMatch represents information about where a match came from when using
|
/// IgnoreMatch represents information about where a match came from when using
|
||||||
/// the `Ignore` matcher.
|
/// the `Ignore` matcher.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct IgnoreMatch<'a>(IgnoreMatchInner<'a>);
|
pub(crate) struct IgnoreMatch<'a>(IgnoreMatchInner<'a>);
|
||||||
|
|
||||||
/// IgnoreMatchInner describes precisely where the match information came from.
|
/// IgnoreMatchInner describes precisely where the match information came from.
|
||||||
/// This is private to allow expansion to more matchers in the future.
|
/// This is private to allow expansion to more matchers in the future.
|
||||||
@ -85,7 +89,7 @@ struct IgnoreOptions {
|
|||||||
|
|
||||||
/// Ignore is a matcher useful for recursively walking one or more directories.
|
/// Ignore is a matcher useful for recursively walking one or more directories.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Ignore(Arc<IgnoreInner>);
|
pub(crate) struct Ignore(Arc<IgnoreInner>);
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
struct IgnoreInner {
|
struct IgnoreInner {
|
||||||
@ -134,22 +138,22 @@ struct IgnoreInner {
|
|||||||
|
|
||||||
impl Ignore {
|
impl Ignore {
|
||||||
/// Return the directory path of this matcher.
|
/// Return the directory path of this matcher.
|
||||||
pub fn path(&self) -> &Path {
|
pub(crate) fn path(&self) -> &Path {
|
||||||
&self.0.dir
|
&self.0.dir
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return true if this matcher has no parent.
|
/// Return true if this matcher has no parent.
|
||||||
pub fn is_root(&self) -> bool {
|
pub(crate) fn is_root(&self) -> bool {
|
||||||
self.0.parent.is_none()
|
self.0.parent.is_none()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if this matcher was added via the `add_parents` method.
|
/// Returns true if this matcher was added via the `add_parents` method.
|
||||||
pub fn is_absolute_parent(&self) -> bool {
|
pub(crate) fn is_absolute_parent(&self) -> bool {
|
||||||
self.0.is_absolute_parent
|
self.0.is_absolute_parent
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return this matcher's parent, if one exists.
|
/// Return this matcher's parent, if one exists.
|
||||||
pub fn parent(&self) -> Option<Ignore> {
|
pub(crate) fn parent(&self) -> Option<Ignore> {
|
||||||
self.0.parent.clone()
|
self.0.parent.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,7 +161,7 @@ impl Ignore {
|
|||||||
///
|
///
|
||||||
/// Note that this can only be called on an `Ignore` matcher with no
|
/// Note that this can only be called on an `Ignore` matcher with no
|
||||||
/// parents (i.e., `is_root` returns `true`). This will panic otherwise.
|
/// parents (i.e., `is_root` returns `true`). This will panic otherwise.
|
||||||
pub fn add_parents<P: AsRef<Path>>(
|
pub(crate) fn add_parents<P: AsRef<Path>>(
|
||||||
&self,
|
&self,
|
||||||
path: P,
|
path: P,
|
||||||
) -> (Ignore, Option<Error>) {
|
) -> (Ignore, Option<Error>) {
|
||||||
@ -222,7 +226,7 @@ impl Ignore {
|
|||||||
/// returned if it exists.
|
/// returned if it exists.
|
||||||
///
|
///
|
||||||
/// Note that all I/O errors are completely ignored.
|
/// Note that all I/O errors are completely ignored.
|
||||||
pub fn add_child<P: AsRef<Path>>(
|
pub(crate) fn add_child<P: AsRef<Path>>(
|
||||||
&self,
|
&self,
|
||||||
dir: P,
|
dir: P,
|
||||||
) -> (Ignore, Option<Error>) {
|
) -> (Ignore, Option<Error>) {
|
||||||
@ -335,7 +339,7 @@ impl Ignore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Like `matched`, but works with a directory entry instead.
|
/// Like `matched`, but works with a directory entry instead.
|
||||||
pub fn matched_dir_entry<'a>(
|
pub(crate) fn matched_dir_entry<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
dent: &DirEntry,
|
dent: &DirEntry,
|
||||||
) -> Match<IgnoreMatch<'a>> {
|
) -> Match<IgnoreMatch<'a>> {
|
||||||
@ -520,7 +524,7 @@ impl Ignore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns an iterator over parent ignore matchers, including this one.
|
/// Returns an iterator over parent ignore matchers, including this one.
|
||||||
pub fn parents(&self) -> Parents<'_> {
|
pub(crate) fn parents(&self) -> Parents<'_> {
|
||||||
Parents(Some(self))
|
Parents(Some(self))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -534,7 +538,7 @@ impl Ignore {
|
|||||||
/// An iterator over all parents of an ignore matcher, including itself.
|
/// An iterator over all parents of an ignore matcher, including itself.
|
||||||
///
|
///
|
||||||
/// The lifetime `'a` refers to the lifetime of the initial `Ignore` matcher.
|
/// The lifetime `'a` refers to the lifetime of the initial `Ignore` matcher.
|
||||||
pub struct Parents<'a>(Option<&'a Ignore>);
|
pub(crate) struct Parents<'a>(Option<&'a Ignore>);
|
||||||
|
|
||||||
impl<'a> Iterator for Parents<'a> {
|
impl<'a> Iterator for Parents<'a> {
|
||||||
type Item = &'a Ignore;
|
type Item = &'a Ignore;
|
||||||
@ -552,7 +556,7 @@ impl<'a> Iterator for Parents<'a> {
|
|||||||
|
|
||||||
/// A builder for creating an Ignore matcher.
|
/// A builder for creating an Ignore matcher.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct IgnoreBuilder {
|
pub(crate) struct IgnoreBuilder {
|
||||||
/// The root directory path for this ignore matcher.
|
/// The root directory path for this ignore matcher.
|
||||||
dir: PathBuf,
|
dir: PathBuf,
|
||||||
/// An override matcher (default is empty).
|
/// An override matcher (default is empty).
|
||||||
@ -572,7 +576,7 @@ impl IgnoreBuilder {
|
|||||||
///
|
///
|
||||||
/// All relative file paths are resolved with respect to the current
|
/// All relative file paths are resolved with respect to the current
|
||||||
/// working directory.
|
/// working directory.
|
||||||
pub fn new() -> IgnoreBuilder {
|
pub(crate) fn new() -> IgnoreBuilder {
|
||||||
IgnoreBuilder {
|
IgnoreBuilder {
|
||||||
dir: Path::new("").to_path_buf(),
|
dir: Path::new("").to_path_buf(),
|
||||||
overrides: Arc::new(Override::empty()),
|
overrides: Arc::new(Override::empty()),
|
||||||
@ -596,7 +600,7 @@ impl IgnoreBuilder {
|
|||||||
///
|
///
|
||||||
/// The matcher returned won't match anything until ignore rules from
|
/// The matcher returned won't match anything until ignore rules from
|
||||||
/// directories are added to it.
|
/// directories are added to it.
|
||||||
pub fn build(&self) -> Ignore {
|
pub(crate) fn build(&self) -> Ignore {
|
||||||
let git_global_matcher = if !self.opts.git_global {
|
let git_global_matcher = if !self.opts.git_global {
|
||||||
Gitignore::empty()
|
Gitignore::empty()
|
||||||
} else {
|
} else {
|
||||||
@ -638,7 +642,10 @@ impl IgnoreBuilder {
|
|||||||
/// By default, no override matcher is used.
|
/// By default, no override matcher is used.
|
||||||
///
|
///
|
||||||
/// This overrides any previous setting.
|
/// This overrides any previous setting.
|
||||||
pub fn overrides(&mut self, overrides: Override) -> &mut IgnoreBuilder {
|
pub(crate) fn overrides(
|
||||||
|
&mut self,
|
||||||
|
overrides: Override,
|
||||||
|
) -> &mut IgnoreBuilder {
|
||||||
self.overrides = Arc::new(overrides);
|
self.overrides = Arc::new(overrides);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@ -648,13 +655,13 @@ impl IgnoreBuilder {
|
|||||||
/// By default, no file type matcher is used.
|
/// By default, no file type matcher is used.
|
||||||
///
|
///
|
||||||
/// This overrides any previous setting.
|
/// This overrides any previous setting.
|
||||||
pub fn types(&mut self, types: Types) -> &mut IgnoreBuilder {
|
pub(crate) fn types(&mut self, types: Types) -> &mut IgnoreBuilder {
|
||||||
self.types = Arc::new(types);
|
self.types = Arc::new(types);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Adds a new global ignore matcher from the ignore file path given.
|
/// Adds a new global ignore matcher from the ignore file path given.
|
||||||
pub fn add_ignore(&mut self, ig: Gitignore) -> &mut IgnoreBuilder {
|
pub(crate) fn add_ignore(&mut self, ig: Gitignore) -> &mut IgnoreBuilder {
|
||||||
self.explicit_ignores.push(ig);
|
self.explicit_ignores.push(ig);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@ -665,7 +672,7 @@ impl IgnoreBuilder {
|
|||||||
///
|
///
|
||||||
/// When specifying multiple names, earlier names have lower precedence than
|
/// When specifying multiple names, earlier names have lower precedence than
|
||||||
/// later names.
|
/// later names.
|
||||||
pub fn add_custom_ignore_filename<S: AsRef<OsStr>>(
|
pub(crate) fn add_custom_ignore_filename<S: AsRef<OsStr>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
file_name: S,
|
file_name: S,
|
||||||
) -> &mut IgnoreBuilder {
|
) -> &mut IgnoreBuilder {
|
||||||
@ -676,7 +683,7 @@ impl IgnoreBuilder {
|
|||||||
/// Enables ignoring hidden files.
|
/// Enables ignoring hidden files.
|
||||||
///
|
///
|
||||||
/// This is enabled by default.
|
/// This is enabled by default.
|
||||||
pub fn hidden(&mut self, yes: bool) -> &mut IgnoreBuilder {
|
pub(crate) fn hidden(&mut self, yes: bool) -> &mut IgnoreBuilder {
|
||||||
self.opts.hidden = yes;
|
self.opts.hidden = yes;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@ -687,7 +694,7 @@ impl IgnoreBuilder {
|
|||||||
/// supported by search tools such as ripgrep and The Silver Searcher.
|
/// supported by search tools such as ripgrep and The Silver Searcher.
|
||||||
///
|
///
|
||||||
/// This is enabled by default.
|
/// This is enabled by default.
|
||||||
pub fn ignore(&mut self, yes: bool) -> &mut IgnoreBuilder {
|
pub(crate) fn ignore(&mut self, yes: bool) -> &mut IgnoreBuilder {
|
||||||
self.opts.ignore = yes;
|
self.opts.ignore = yes;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@ -698,7 +705,7 @@ impl IgnoreBuilder {
|
|||||||
/// file path given are respected. Otherwise, they are ignored.
|
/// file path given are respected. Otherwise, they are ignored.
|
||||||
///
|
///
|
||||||
/// This is enabled by default.
|
/// This is enabled by default.
|
||||||
pub fn parents(&mut self, yes: bool) -> &mut IgnoreBuilder {
|
pub(crate) fn parents(&mut self, yes: bool) -> &mut IgnoreBuilder {
|
||||||
self.opts.parents = yes;
|
self.opts.parents = yes;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@ -711,7 +718,7 @@ impl IgnoreBuilder {
|
|||||||
/// This overwrites any previous global gitignore setting.
|
/// This overwrites any previous global gitignore setting.
|
||||||
///
|
///
|
||||||
/// This is enabled by default.
|
/// This is enabled by default.
|
||||||
pub fn git_global(&mut self, yes: bool) -> &mut IgnoreBuilder {
|
pub(crate) fn git_global(&mut self, yes: bool) -> &mut IgnoreBuilder {
|
||||||
self.opts.git_global = yes;
|
self.opts.git_global = yes;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@ -722,7 +729,7 @@ impl IgnoreBuilder {
|
|||||||
/// man page.
|
/// man page.
|
||||||
///
|
///
|
||||||
/// This is enabled by default.
|
/// This is enabled by default.
|
||||||
pub fn git_ignore(&mut self, yes: bool) -> &mut IgnoreBuilder {
|
pub(crate) fn git_ignore(&mut self, yes: bool) -> &mut IgnoreBuilder {
|
||||||
self.opts.git_ignore = yes;
|
self.opts.git_ignore = yes;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@ -733,7 +740,7 @@ impl IgnoreBuilder {
|
|||||||
/// `gitignore` man page.
|
/// `gitignore` man page.
|
||||||
///
|
///
|
||||||
/// This is enabled by default.
|
/// This is enabled by default.
|
||||||
pub fn git_exclude(&mut self, yes: bool) -> &mut IgnoreBuilder {
|
pub(crate) fn git_exclude(&mut self, yes: bool) -> &mut IgnoreBuilder {
|
||||||
self.opts.git_exclude = yes;
|
self.opts.git_exclude = yes;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@ -743,7 +750,7 @@ impl IgnoreBuilder {
|
|||||||
///
|
///
|
||||||
/// When disabled, git-related ignore rules are applied even when searching
|
/// When disabled, git-related ignore rules are applied even when searching
|
||||||
/// outside a git repository.
|
/// outside a git repository.
|
||||||
pub fn require_git(&mut self, yes: bool) -> &mut IgnoreBuilder {
|
pub(crate) fn require_git(&mut self, yes: bool) -> &mut IgnoreBuilder {
|
||||||
self.opts.require_git = yes;
|
self.opts.require_git = yes;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@ -751,7 +758,7 @@ impl IgnoreBuilder {
|
|||||||
/// Process ignore files case insensitively
|
/// Process ignore files case insensitively
|
||||||
///
|
///
|
||||||
/// This is disabled by default.
|
/// This is disabled by default.
|
||||||
pub fn ignore_case_insensitive(
|
pub(crate) fn ignore_case_insensitive(
|
||||||
&mut self,
|
&mut self,
|
||||||
yes: bool,
|
yes: bool,
|
||||||
) -> &mut IgnoreBuilder {
|
) -> &mut IgnoreBuilder {
|
||||||
@ -768,7 +775,7 @@ impl IgnoreBuilder {
|
|||||||
/// precedence than later names).
|
/// precedence than later names).
|
||||||
///
|
///
|
||||||
/// I/O errors are ignored.
|
/// I/O errors are ignored.
|
||||||
pub fn create_gitignore<T: AsRef<OsStr>>(
|
pub(crate) fn create_gitignore<T: AsRef<OsStr>>(
|
||||||
dir: &Path,
|
dir: &Path,
|
||||||
dir_for_ignorefile: &Path,
|
dir_for_ignorefile: &Path,
|
||||||
names: &[T],
|
names: &[T],
|
||||||
@ -861,22 +868,19 @@ fn resolve_git_commondir(
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use std::fs::{self, File};
|
use std::{io::Write, path::Path};
|
||||||
use std::io::Write;
|
|
||||||
use std::path::Path;
|
|
||||||
|
|
||||||
use crate::dir::IgnoreBuilder;
|
use crate::{
|
||||||
use crate::gitignore::Gitignore;
|
dir::IgnoreBuilder, gitignore::Gitignore, tests::TempDir, Error,
|
||||||
use crate::tests::TempDir;
|
};
|
||||||
use crate::Error;
|
|
||||||
|
|
||||||
fn wfile<P: AsRef<Path>>(path: P, contents: &str) {
|
fn wfile<P: AsRef<Path>>(path: P, contents: &str) {
|
||||||
let mut file = File::create(path).unwrap();
|
let mut file = std::fs::File::create(path).unwrap();
|
||||||
file.write_all(contents.as_bytes()).unwrap();
|
file.write_all(contents.as_bytes()).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mkdirp<P: AsRef<Path>>(path: P) {
|
fn mkdirp<P: AsRef<Path>>(path: P) {
|
||||||
fs::create_dir_all(path).unwrap();
|
std::fs::create_dir_all(path).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn partial(err: Error) -> Vec<Error> {
|
fn partial(err: Error) -> Vec<Error> {
|
||||||
@ -1193,7 +1197,7 @@ mod tests {
|
|||||||
assert!(ignore.matched("ignore_me", false).is_ignore());
|
assert!(ignore.matched("ignore_me", false).is_ignore());
|
||||||
|
|
||||||
// missing commondir file
|
// missing commondir file
|
||||||
assert!(fs::remove_file(commondir_path()).is_ok());
|
assert!(std::fs::remove_file(commondir_path()).is_ok());
|
||||||
let (_, err) = ib.add_child(td.path().join("linked-worktree"));
|
let (_, err) = ib.add_child(td.path().join("linked-worktree"));
|
||||||
// We squash the error in this case, because it occurs in repositories
|
// We squash the error in this case, because it occurs in repositories
|
||||||
// that are not linked worktrees but have submodules.
|
// that are not linked worktrees but have submodules.
|
||||||
|
@ -7,20 +7,24 @@ Note that this module implements the specification as described in the
|
|||||||
the `git` command line tool.
|
the `git` command line tool.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use std::cell::RefCell;
|
use std::{
|
||||||
use std::env;
|
cell::RefCell,
|
||||||
use std::fs::File;
|
fs::File,
|
||||||
use std::io::{self, BufRead, Read};
|
io::{BufRead, BufReader, Read},
|
||||||
use std::path::{Path, PathBuf};
|
path::{Path, PathBuf},
|
||||||
use std::str;
|
sync::Arc,
|
||||||
use std::sync::Arc;
|
};
|
||||||
|
|
||||||
use globset::{Candidate, GlobBuilder, GlobSet, GlobSetBuilder};
|
use {
|
||||||
use regex::bytes::Regex;
|
globset::{Candidate, GlobBuilder, GlobSet, GlobSetBuilder},
|
||||||
use thread_local::ThreadLocal;
|
regex::bytes::Regex,
|
||||||
|
thread_local::ThreadLocal,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::pathutil::{is_file_name, strip_prefix};
|
use crate::{
|
||||||
use crate::{Error, Match, PartialErrorBuilder};
|
pathutil::{is_file_name, strip_prefix},
|
||||||
|
Error, Match, PartialErrorBuilder,
|
||||||
|
};
|
||||||
|
|
||||||
/// Glob represents a single glob in a gitignore file.
|
/// Glob represents a single glob in a gitignore file.
|
||||||
///
|
///
|
||||||
@ -337,7 +341,7 @@ impl GitignoreBuilder {
|
|||||||
.build()
|
.build()
|
||||||
.map_err(|err| Error::Glob { glob: None, err: err.to_string() })?;
|
.map_err(|err| Error::Glob { glob: None, err: err.to_string() })?;
|
||||||
Ok(Gitignore {
|
Ok(Gitignore {
|
||||||
set: set,
|
set,
|
||||||
root: self.root.clone(),
|
root: self.root.clone(),
|
||||||
globs: self.globs.clone(),
|
globs: self.globs.clone(),
|
||||||
num_ignores: nignore as u64,
|
num_ignores: nignore as u64,
|
||||||
@ -389,7 +393,7 @@ impl GitignoreBuilder {
|
|||||||
Err(err) => return Some(Error::Io(err).with_path(path)),
|
Err(err) => return Some(Error::Io(err).with_path(path)),
|
||||||
Ok(file) => file,
|
Ok(file) => file,
|
||||||
};
|
};
|
||||||
let rdr = io::BufReader::new(file);
|
let rdr = BufReader::new(file);
|
||||||
let mut errs = PartialErrorBuilder::default();
|
let mut errs = PartialErrorBuilder::default();
|
||||||
for (i, line) in rdr.lines().enumerate() {
|
for (i, line) in rdr.lines().enumerate() {
|
||||||
let lineno = (i + 1) as u64;
|
let lineno = (i + 1) as u64;
|
||||||
@ -448,7 +452,7 @@ impl GitignoreBuilder {
|
|||||||
return Ok(self);
|
return Ok(self);
|
||||||
}
|
}
|
||||||
let mut glob = Glob {
|
let mut glob = Glob {
|
||||||
from: from,
|
from,
|
||||||
original: line.to_string(),
|
original: line.to_string(),
|
||||||
actual: String::new(),
|
actual: String::new(),
|
||||||
is_whitelist: false,
|
is_whitelist: false,
|
||||||
@ -558,7 +562,7 @@ fn gitconfig_home_contents() -> Option<Vec<u8>> {
|
|||||||
};
|
};
|
||||||
let mut file = match File::open(home.join(".gitconfig")) {
|
let mut file = match File::open(home.join(".gitconfig")) {
|
||||||
Err(_) => return None,
|
Err(_) => return None,
|
||||||
Ok(file) => io::BufReader::new(file),
|
Ok(file) => BufReader::new(file),
|
||||||
};
|
};
|
||||||
let mut contents = vec![];
|
let mut contents = vec![];
|
||||||
file.read_to_end(&mut contents).ok().map(|_| contents)
|
file.read_to_end(&mut contents).ok().map(|_| contents)
|
||||||
@ -567,13 +571,13 @@ fn gitconfig_home_contents() -> Option<Vec<u8>> {
|
|||||||
/// Returns the file contents of git's global config file, if one exists, in
|
/// Returns the file contents of git's global config file, if one exists, in
|
||||||
/// the user's XDG_CONFIG_HOME directory.
|
/// the user's XDG_CONFIG_HOME directory.
|
||||||
fn gitconfig_xdg_contents() -> Option<Vec<u8>> {
|
fn gitconfig_xdg_contents() -> Option<Vec<u8>> {
|
||||||
let path = env::var_os("XDG_CONFIG_HOME")
|
let path = std::env::var_os("XDG_CONFIG_HOME")
|
||||||
.and_then(|x| if x.is_empty() { None } else { Some(PathBuf::from(x)) })
|
.and_then(|x| if x.is_empty() { None } else { Some(PathBuf::from(x)) })
|
||||||
.or_else(|| home_dir().map(|p| p.join(".config")))
|
.or_else(|| home_dir().map(|p| p.join(".config")))
|
||||||
.map(|x| x.join("git/config"));
|
.map(|x| x.join("git/config"));
|
||||||
let mut file = match path.and_then(|p| File::open(p).ok()) {
|
let mut file = match path.and_then(|p| File::open(p).ok()) {
|
||||||
None => return None,
|
None => return None,
|
||||||
Some(file) => io::BufReader::new(file),
|
Some(file) => BufReader::new(file),
|
||||||
};
|
};
|
||||||
let mut contents = vec![];
|
let mut contents = vec![];
|
||||||
file.read_to_end(&mut contents).ok().map(|_| contents)
|
file.read_to_end(&mut contents).ok().map(|_| contents)
|
||||||
@ -583,7 +587,7 @@ fn gitconfig_xdg_contents() -> Option<Vec<u8>> {
|
|||||||
///
|
///
|
||||||
/// Specifically, this respects XDG_CONFIG_HOME.
|
/// Specifically, this respects XDG_CONFIG_HOME.
|
||||||
fn excludes_file_default() -> Option<PathBuf> {
|
fn excludes_file_default() -> Option<PathBuf> {
|
||||||
env::var_os("XDG_CONFIG_HOME")
|
std::env::var_os("XDG_CONFIG_HOME")
|
||||||
.and_then(|x| if x.is_empty() { None } else { Some(PathBuf::from(x)) })
|
.and_then(|x| if x.is_empty() { None } else { Some(PathBuf::from(x)) })
|
||||||
.or_else(|| home_dir().map(|p| p.join(".config")))
|
.or_else(|| home_dir().map(|p| p.join(".config")))
|
||||||
.map(|x| x.join("git/ignore"))
|
.map(|x| x.join("git/ignore"))
|
||||||
@ -608,7 +612,7 @@ fn parse_excludes_file(data: &[u8]) -> Option<PathBuf> {
|
|||||||
None => return None,
|
None => return None,
|
||||||
Some(caps) => caps,
|
Some(caps) => caps,
|
||||||
};
|
};
|
||||||
str::from_utf8(&caps[1]).ok().map(|s| PathBuf::from(expand_tilde(s)))
|
std::str::from_utf8(&caps[1]).ok().map(|s| PathBuf::from(expand_tilde(s)))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Expands ~ in file paths to the value of $HOME.
|
/// Expands ~ in file paths to the value of $HOME.
|
||||||
@ -622,18 +626,18 @@ fn expand_tilde(path: &str) -> String {
|
|||||||
|
|
||||||
/// Returns the location of the user's home directory.
|
/// Returns the location of the user's home directory.
|
||||||
fn home_dir() -> Option<PathBuf> {
|
fn home_dir() -> Option<PathBuf> {
|
||||||
// We're fine with using env::home_dir for now. Its bugs are, IMO, pretty
|
// We're fine with using std::env::home_dir for now. Its bugs are, IMO,
|
||||||
// minor corner cases. We should still probably eventually migrate to
|
// pretty minor corner cases.
|
||||||
// the `dirs` crate to get a proper implementation.
|
|
||||||
#![allow(deprecated)]
|
#![allow(deprecated)]
|
||||||
env::home_dir()
|
std::env::home_dir()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::{Gitignore, GitignoreBuilder};
|
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
|
use super::{Gitignore, GitignoreBuilder};
|
||||||
|
|
||||||
fn gi_from_str<P: AsRef<Path>>(root: P, s: &str) -> Gitignore {
|
fn gi_from_str<P: AsRef<Path>>(root: P, s: &str) -> Gitignore {
|
||||||
let mut builder = GitignoreBuilder::new(root);
|
let mut builder = GitignoreBuilder::new(root);
|
||||||
builder.add_str(None, s).unwrap();
|
builder.add_str(None, s).unwrap();
|
||||||
|
@ -46,9 +46,6 @@ See the documentation for `WalkBuilder` for many other options.
|
|||||||
|
|
||||||
#![deny(missing_docs)]
|
#![deny(missing_docs)]
|
||||||
|
|
||||||
use std::error;
|
|
||||||
use std::fmt;
|
|
||||||
use std::io;
|
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
pub use crate::walk::{
|
pub use crate::walk::{
|
||||||
@ -101,7 +98,7 @@ pub enum Error {
|
|||||||
child: PathBuf,
|
child: PathBuf,
|
||||||
},
|
},
|
||||||
/// An error that occurs when doing I/O, such as reading an ignore file.
|
/// An error that occurs when doing I/O, such as reading an ignore file.
|
||||||
Io(io::Error),
|
Io(std::io::Error),
|
||||||
/// An error that occurs when trying to parse a glob.
|
/// An error that occurs when trying to parse a glob.
|
||||||
Glob {
|
Glob {
|
||||||
/// The original glob that caused this error. This glob, when
|
/// The original glob that caused this error. This glob, when
|
||||||
@ -125,21 +122,23 @@ impl Clone for Error {
|
|||||||
match *self {
|
match *self {
|
||||||
Error::Partial(ref errs) => Error::Partial(errs.clone()),
|
Error::Partial(ref errs) => Error::Partial(errs.clone()),
|
||||||
Error::WithLineNumber { line, ref err } => {
|
Error::WithLineNumber { line, ref err } => {
|
||||||
Error::WithLineNumber { line: line, err: err.clone() }
|
Error::WithLineNumber { line, err: err.clone() }
|
||||||
}
|
}
|
||||||
Error::WithPath { ref path, ref err } => {
|
Error::WithPath { ref path, ref err } => {
|
||||||
Error::WithPath { path: path.clone(), err: err.clone() }
|
Error::WithPath { path: path.clone(), err: err.clone() }
|
||||||
}
|
}
|
||||||
Error::WithDepth { depth, ref err } => {
|
Error::WithDepth { depth, ref err } => {
|
||||||
Error::WithDepth { depth: depth, err: err.clone() }
|
Error::WithDepth { depth, err: err.clone() }
|
||||||
}
|
}
|
||||||
Error::Loop { ref ancestor, ref child } => Error::Loop {
|
Error::Loop { ref ancestor, ref child } => Error::Loop {
|
||||||
ancestor: ancestor.clone(),
|
ancestor: ancestor.clone(),
|
||||||
child: child.clone(),
|
child: child.clone(),
|
||||||
},
|
},
|
||||||
Error::Io(ref err) => match err.raw_os_error() {
|
Error::Io(ref err) => match err.raw_os_error() {
|
||||||
Some(e) => Error::Io(io::Error::from_raw_os_error(e)),
|
Some(e) => Error::Io(std::io::Error::from_raw_os_error(e)),
|
||||||
None => Error::Io(io::Error::new(err.kind(), err.to_string())),
|
None => {
|
||||||
|
Error::Io(std::io::Error::new(err.kind(), err.to_string()))
|
||||||
|
}
|
||||||
},
|
},
|
||||||
Error::Glob { ref glob, ref err } => {
|
Error::Glob { ref glob, ref err } => {
|
||||||
Error::Glob { glob: glob.clone(), err: err.clone() }
|
Error::Glob { glob: glob.clone(), err: err.clone() }
|
||||||
@ -183,22 +182,22 @@ impl Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Inspect the original [`io::Error`] if there is one.
|
/// Inspect the original [`std::io::Error`] if there is one.
|
||||||
///
|
///
|
||||||
/// [`None`] is returned if the [`Error`] doesn't correspond to an
|
/// [`None`] is returned if the [`Error`] doesn't correspond to an
|
||||||
/// [`io::Error`]. This might happen, for example, when the error was
|
/// [`std::io::Error`]. This might happen, for example, when the error was
|
||||||
/// produced because a cycle was found in the directory tree while
|
/// produced because a cycle was found in the directory tree while
|
||||||
/// following symbolic links.
|
/// following symbolic links.
|
||||||
///
|
///
|
||||||
/// This method returns a borrowed value that is bound to the lifetime of the [`Error`]. To
|
/// This method returns a borrowed value that is bound to the lifetime of the [`Error`]. To
|
||||||
/// obtain an owned value, the [`into_io_error`] can be used instead.
|
/// obtain an owned value, the [`into_io_error`] can be used instead.
|
||||||
///
|
///
|
||||||
/// > This is the original [`io::Error`] and is _not_ the same as
|
/// > This is the original [`std::io::Error`] and is _not_ the same as
|
||||||
/// > [`impl From<Error> for std::io::Error`][impl] which contains additional context about the
|
/// > [`impl From<Error> for std::io::Error`][impl] which contains
|
||||||
/// error.
|
/// > additional context about the error.
|
||||||
///
|
///
|
||||||
/// [`None`]: https://doc.rust-lang.org/stable/std/option/enum.Option.html#variant.None
|
/// [`None`]: https://doc.rust-lang.org/stable/std/option/enum.Option.html#variant.None
|
||||||
/// [`io::Error`]: https://doc.rust-lang.org/stable/std/io/struct.Error.html
|
/// [`std::io::Error`]: https://doc.rust-lang.org/stable/std/io/struct.Error.html
|
||||||
/// [`From`]: https://doc.rust-lang.org/stable/std/convert/trait.From.html
|
/// [`From`]: https://doc.rust-lang.org/stable/std/convert/trait.From.html
|
||||||
/// [`Error`]: struct.Error.html
|
/// [`Error`]: struct.Error.html
|
||||||
/// [`into_io_error`]: struct.Error.html#method.into_io_error
|
/// [`into_io_error`]: struct.Error.html#method.into_io_error
|
||||||
@ -224,10 +223,10 @@ impl Error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Similar to [`io_error`] except consumes self to convert to the original
|
/// Similar to [`io_error`] except consumes self to convert to the original
|
||||||
/// [`io::Error`] if one exists.
|
/// [`std::io::Error`] if one exists.
|
||||||
///
|
///
|
||||||
/// [`io_error`]: struct.Error.html#method.io_error
|
/// [`io_error`]: struct.Error.html#method.io_error
|
||||||
/// [`io::Error`]: https://doc.rust-lang.org/stable/std/io/struct.Error.html
|
/// [`std::io::Error`]: https://doc.rust-lang.org/stable/std/io/struct.Error.html
|
||||||
pub fn into_io_error(self) -> Option<std::io::Error> {
|
pub fn into_io_error(self) -> Option<std::io::Error> {
|
||||||
match self {
|
match self {
|
||||||
Error::Partial(mut errs) => {
|
Error::Partial(mut errs) => {
|
||||||
@ -268,7 +267,7 @@ impl Error {
|
|||||||
|
|
||||||
/// Turn an error into a tagged error with the given depth.
|
/// Turn an error into a tagged error with the given depth.
|
||||||
fn with_depth(self, depth: usize) -> Error {
|
fn with_depth(self, depth: usize) -> Error {
|
||||||
Error::WithDepth { depth: depth, err: Box::new(self) }
|
Error::WithDepth { depth, err: Box::new(self) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Turn an error into a tagged error with the given file path and line
|
/// Turn an error into a tagged error with the given file path and line
|
||||||
@ -287,7 +286,7 @@ impl Error {
|
|||||||
let depth = err.depth();
|
let depth = err.depth();
|
||||||
if let (Some(anc), Some(child)) = (err.loop_ancestor(), err.path()) {
|
if let (Some(anc), Some(child)) = (err.loop_ancestor(), err.path()) {
|
||||||
return Error::WithDepth {
|
return Error::WithDepth {
|
||||||
depth: depth,
|
depth,
|
||||||
err: Box::new(Error::Loop {
|
err: Box::new(Error::Loop {
|
||||||
ancestor: anc.to_path_buf(),
|
ancestor: anc.to_path_buf(),
|
||||||
child: child.to_path_buf(),
|
child: child.to_path_buf(),
|
||||||
@ -295,15 +294,15 @@ impl Error {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
let path = err.path().map(|p| p.to_path_buf());
|
let path = err.path().map(|p| p.to_path_buf());
|
||||||
let mut ig_err = Error::Io(io::Error::from(err));
|
let mut ig_err = Error::Io(std::io::Error::from(err));
|
||||||
if let Some(path) = path {
|
if let Some(path) = path {
|
||||||
ig_err = Error::WithPath { path: path, err: Box::new(ig_err) };
|
ig_err = Error::WithPath { path, err: Box::new(ig_err) };
|
||||||
}
|
}
|
||||||
ig_err
|
ig_err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl error::Error for Error {
|
impl std::error::Error for Error {
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
fn description(&self) -> &str {
|
fn description(&self) -> &str {
|
||||||
match *self {
|
match *self {
|
||||||
@ -320,8 +319,8 @@ impl error::Error for Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for Error {
|
impl std::fmt::Display for Error {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
match *self {
|
match *self {
|
||||||
Error::Partial(ref errs) => {
|
Error::Partial(ref errs) => {
|
||||||
let msgs: Vec<String> =
|
let msgs: Vec<String> =
|
||||||
@ -359,8 +358,8 @@ impl fmt::Display for Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<io::Error> for Error {
|
impl From<std::io::Error> for Error {
|
||||||
fn from(err: io::Error) -> Error {
|
fn from(err: std::io::Error) -> Error {
|
||||||
Error::Io(err)
|
Error::Io(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -488,19 +487,18 @@ impl<T> Match<T> {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use std::env;
|
use std::{
|
||||||
use std::error;
|
env, fs,
|
||||||
use std::fs;
|
path::{Path, PathBuf},
|
||||||
use std::path::{Path, PathBuf};
|
};
|
||||||
use std::result;
|
|
||||||
|
|
||||||
/// A convenient result type alias.
|
/// A convenient result type alias.
|
||||||
pub type Result<T> =
|
pub(crate) type Result<T> =
|
||||||
result::Result<T, Box<dyn error::Error + Send + Sync>>;
|
std::result::Result<T, Box<dyn std::error::Error + Send + Sync>>;
|
||||||
|
|
||||||
macro_rules! err {
|
macro_rules! err {
|
||||||
($($tt:tt)*) => {
|
($($tt:tt)*) => {
|
||||||
Box::<dyn error::Error + Send + Sync>::from(format!($($tt)*))
|
Box::<dyn std::error::Error + Send + Sync>::from(format!($($tt)*))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,8 +6,10 @@ line tools.
|
|||||||
|
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
use crate::gitignore::{self, Gitignore, GitignoreBuilder};
|
use crate::{
|
||||||
use crate::{Error, Match};
|
gitignore::{self, Gitignore, GitignoreBuilder},
|
||||||
|
Error, Match,
|
||||||
|
};
|
||||||
|
|
||||||
/// Glob represents a single glob in an override matcher.
|
/// Glob represents a single glob in an override matcher.
|
||||||
///
|
///
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
use std::ffi::OsStr;
|
use std::{ffi::OsStr, path::Path};
|
||||||
use std::path::Path;
|
|
||||||
|
|
||||||
use crate::walk::DirEntry;
|
use crate::walk::DirEntry;
|
||||||
|
|
||||||
@ -9,7 +8,7 @@ use crate::walk::DirEntry;
|
|||||||
///
|
///
|
||||||
/// On Unix, this implements a more optimized check.
|
/// On Unix, this implements a more optimized check.
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
pub fn is_hidden(dent: &DirEntry) -> bool {
|
pub(crate) fn is_hidden(dent: &DirEntry) -> bool {
|
||||||
use std::os::unix::ffi::OsStrExt;
|
use std::os::unix::ffi::OsStrExt;
|
||||||
|
|
||||||
if let Some(name) = file_name(dent.path()) {
|
if let Some(name) = file_name(dent.path()) {
|
||||||
@ -26,7 +25,7 @@ pub fn is_hidden(dent: &DirEntry) -> bool {
|
|||||||
/// * The base name of the path starts with a `.`.
|
/// * The base name of the path starts with a `.`.
|
||||||
/// * The file attributes have the `HIDDEN` property set.
|
/// * The file attributes have the `HIDDEN` property set.
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
pub fn is_hidden(dent: &DirEntry) -> bool {
|
pub(crate) fn is_hidden(dent: &DirEntry) -> bool {
|
||||||
use std::os::windows::fs::MetadataExt;
|
use std::os::windows::fs::MetadataExt;
|
||||||
use winapi_util::file;
|
use winapi_util::file;
|
||||||
|
|
||||||
@ -49,7 +48,7 @@ pub fn is_hidden(dent: &DirEntry) -> bool {
|
|||||||
///
|
///
|
||||||
/// This only returns true if the base name of the path starts with a `.`.
|
/// This only returns true if the base name of the path starts with a `.`.
|
||||||
#[cfg(not(any(unix, windows)))]
|
#[cfg(not(any(unix, windows)))]
|
||||||
pub fn is_hidden(dent: &DirEntry) -> bool {
|
pub(crate) fn is_hidden(dent: &DirEntry) -> bool {
|
||||||
if let Some(name) = file_name(dent.path()) {
|
if let Some(name) = file_name(dent.path()) {
|
||||||
name.to_str().map(|s| s.starts_with(".")).unwrap_or(false)
|
name.to_str().map(|s| s.starts_with(".")).unwrap_or(false)
|
||||||
} else {
|
} else {
|
||||||
@ -61,7 +60,7 @@ pub fn is_hidden(dent: &DirEntry) -> bool {
|
|||||||
///
|
///
|
||||||
/// If `path` doesn't have a prefix `prefix`, then return `None`.
|
/// If `path` doesn't have a prefix `prefix`, then return `None`.
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
pub fn strip_prefix<'a, P: AsRef<Path> + ?Sized>(
|
pub(crate) fn strip_prefix<'a, P: AsRef<Path> + ?Sized>(
|
||||||
prefix: &'a P,
|
prefix: &'a P,
|
||||||
path: &'a Path,
|
path: &'a Path,
|
||||||
) -> Option<&'a Path> {
|
) -> Option<&'a Path> {
|
||||||
@ -80,7 +79,7 @@ pub fn strip_prefix<'a, P: AsRef<Path> + ?Sized>(
|
|||||||
///
|
///
|
||||||
/// If `path` doesn't have a prefix `prefix`, then return `None`.
|
/// If `path` doesn't have a prefix `prefix`, then return `None`.
|
||||||
#[cfg(not(unix))]
|
#[cfg(not(unix))]
|
||||||
pub fn strip_prefix<'a, P: AsRef<Path> + ?Sized>(
|
pub(crate) fn strip_prefix<'a, P: AsRef<Path> + ?Sized>(
|
||||||
prefix: &'a P,
|
prefix: &'a P,
|
||||||
path: &'a Path,
|
path: &'a Path,
|
||||||
) -> Option<&'a Path> {
|
) -> Option<&'a Path> {
|
||||||
@ -90,10 +89,11 @@ pub fn strip_prefix<'a, P: AsRef<Path> + ?Sized>(
|
|||||||
/// Returns true if this file path is just a file name. i.e., Its parent is
|
/// Returns true if this file path is just a file name. i.e., Its parent is
|
||||||
/// the empty string.
|
/// the empty string.
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
pub fn is_file_name<P: AsRef<Path>>(path: P) -> bool {
|
pub(crate) fn is_file_name<P: AsRef<Path>>(path: P) -> bool {
|
||||||
use memchr::memchr;
|
|
||||||
use std::os::unix::ffi::OsStrExt;
|
use std::os::unix::ffi::OsStrExt;
|
||||||
|
|
||||||
|
use memchr::memchr;
|
||||||
|
|
||||||
let path = path.as_ref().as_os_str().as_bytes();
|
let path = path.as_ref().as_os_str().as_bytes();
|
||||||
memchr(b'/', path).is_none()
|
memchr(b'/', path).is_none()
|
||||||
}
|
}
|
||||||
@ -101,7 +101,7 @@ pub fn is_file_name<P: AsRef<Path>>(path: P) -> bool {
|
|||||||
/// Returns true if this file path is just a file name. i.e., Its parent is
|
/// Returns true if this file path is just a file name. i.e., Its parent is
|
||||||
/// the empty string.
|
/// the empty string.
|
||||||
#[cfg(not(unix))]
|
#[cfg(not(unix))]
|
||||||
pub fn is_file_name<P: AsRef<Path>>(path: P) -> bool {
|
pub(crate) fn is_file_name<P: AsRef<Path>>(path: P) -> bool {
|
||||||
path.as_ref().parent().map(|p| p.as_os_str().is_empty()).unwrap_or(false)
|
path.as_ref().parent().map(|p| p.as_os_str().is_empty()).unwrap_or(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,7 +110,7 @@ pub fn is_file_name<P: AsRef<Path>>(path: P) -> bool {
|
|||||||
/// If the path terminates in ., .., or consists solely of a root of prefix,
|
/// If the path terminates in ., .., or consists solely of a root of prefix,
|
||||||
/// file_name will return None.
|
/// file_name will return None.
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
pub fn file_name<'a, P: AsRef<Path> + ?Sized>(
|
pub(crate) fn file_name<'a, P: AsRef<Path> + ?Sized>(
|
||||||
path: &'a P,
|
path: &'a P,
|
||||||
) -> Option<&'a OsStr> {
|
) -> Option<&'a OsStr> {
|
||||||
use memchr::memrchr;
|
use memchr::memrchr;
|
||||||
@ -135,7 +135,7 @@ pub fn file_name<'a, P: AsRef<Path> + ?Sized>(
|
|||||||
/// If the path terminates in ., .., or consists solely of a root of prefix,
|
/// If the path terminates in ., .., or consists solely of a root of prefix,
|
||||||
/// file_name will return None.
|
/// file_name will return None.
|
||||||
#[cfg(not(unix))]
|
#[cfg(not(unix))]
|
||||||
pub fn file_name<'a, P: AsRef<Path> + ?Sized>(
|
pub(crate) fn file_name<'a, P: AsRef<Path> + ?Sized>(
|
||||||
path: &'a P,
|
path: &'a P,
|
||||||
) -> Option<&'a OsStr> {
|
) -> Option<&'a OsStr> {
|
||||||
path.as_ref().file_name()
|
path.as_ref().file_name()
|
||||||
|
@ -84,18 +84,15 @@ assert!(matcher.matched("y.cpp", false).is_whitelist());
|
|||||||
```
|
```
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use std::cell::RefCell;
|
use std::{cell::RefCell, collections::HashMap, path::Path, sync::Arc};
|
||||||
use std::collections::HashMap;
|
|
||||||
use std::path::Path;
|
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
use globset::{GlobBuilder, GlobSet, GlobSetBuilder};
|
use {
|
||||||
use regex::Regex;
|
globset::{GlobBuilder, GlobSet, GlobSetBuilder},
|
||||||
use thread_local::ThreadLocal;
|
regex::Regex,
|
||||||
|
thread_local::ThreadLocal,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::default_types::DEFAULT_TYPES;
|
use crate::{default_types::DEFAULT_TYPES, pathutil::file_name, Error, Match};
|
||||||
use crate::pathutil::file_name;
|
|
||||||
use crate::{Error, Match};
|
|
||||||
|
|
||||||
/// Glob represents a single glob in a set of file type definitions.
|
/// Glob represents a single glob in a set of file type definitions.
|
||||||
///
|
///
|
||||||
@ -356,11 +353,11 @@ impl TypesBuilder {
|
|||||||
.build()
|
.build()
|
||||||
.map_err(|err| Error::Glob { glob: None, err: err.to_string() })?;
|
.map_err(|err| Error::Glob { glob: None, err: err.to_string() })?;
|
||||||
Ok(Types {
|
Ok(Types {
|
||||||
defs: defs,
|
defs,
|
||||||
selections: selections,
|
selections,
|
||||||
has_selected: has_selected,
|
has_selected,
|
||||||
glob_to_selection: glob_to_selection,
|
glob_to_selection,
|
||||||
set: set,
|
set,
|
||||||
matches: Arc::new(ThreadLocal::default()),
|
matches: Arc::new(ThreadLocal::default()),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1,25 +1,26 @@
|
|||||||
use std::cmp;
|
use std::{
|
||||||
use std::ffi::OsStr;
|
cmp::Ordering,
|
||||||
use std::fmt;
|
ffi::OsStr,
|
||||||
use std::fs::{self, FileType, Metadata};
|
fs::{self, FileType, Metadata},
|
||||||
use std::io;
|
io,
|
||||||
use std::iter::{self, FusedIterator};
|
path::{Path, PathBuf},
|
||||||
use std::path::{Path, PathBuf};
|
sync::atomic::{AtomicBool, AtomicUsize, Ordering as AtomicOrdering},
|
||||||
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
|
sync::Arc,
|
||||||
use std::sync::Arc;
|
};
|
||||||
use std::thread;
|
|
||||||
use std::time::Duration;
|
|
||||||
use std::vec;
|
|
||||||
|
|
||||||
use crossbeam_deque::{Stealer, Worker as Deque};
|
use {
|
||||||
use same_file::Handle;
|
crossbeam_deque::{Stealer, Worker as Deque},
|
||||||
use walkdir::{self, WalkDir};
|
same_file::Handle,
|
||||||
|
walkdir::{self, WalkDir},
|
||||||
|
};
|
||||||
|
|
||||||
use crate::dir::{Ignore, IgnoreBuilder};
|
use crate::{
|
||||||
use crate::gitignore::GitignoreBuilder;
|
dir::{Ignore, IgnoreBuilder},
|
||||||
use crate::overrides::Override;
|
gitignore::GitignoreBuilder,
|
||||||
use crate::types::Types;
|
overrides::Override,
|
||||||
use crate::{Error, PartialErrorBuilder};
|
types::Types,
|
||||||
|
Error, PartialErrorBuilder,
|
||||||
|
};
|
||||||
|
|
||||||
/// A directory entry with a possible error attached.
|
/// A directory entry with a possible error attached.
|
||||||
///
|
///
|
||||||
@ -107,11 +108,11 @@ impl DirEntry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn new_walkdir(dent: walkdir::DirEntry, err: Option<Error>) -> DirEntry {
|
fn new_walkdir(dent: walkdir::DirEntry, err: Option<Error>) -> DirEntry {
|
||||||
DirEntry { dent: DirEntryInner::Walkdir(dent), err: err }
|
DirEntry { dent: DirEntryInner::Walkdir(dent), err }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_raw(dent: DirEntryRaw, err: Option<Error>) -> DirEntry {
|
fn new_raw(dent: DirEntryRaw, err: Option<Error>) -> DirEntry {
|
||||||
DirEntry { dent: DirEntryInner::Raw(dent), err: err }
|
DirEntry { dent: DirEntryInner::Raw(dent), err }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -251,8 +252,8 @@ struct DirEntryRaw {
|
|||||||
metadata: fs::Metadata,
|
metadata: fs::Metadata,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Debug for DirEntryRaw {
|
impl std::fmt::Debug for DirEntryRaw {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
// Leaving out FileType because it doesn't have a debug impl
|
// Leaving out FileType because it doesn't have a debug impl
|
||||||
// in Rust 1.9. We could add it if we really wanted to by manually
|
// in Rust 1.9. We could add it if we really wanted to by manually
|
||||||
// querying each possibly file type. Meh. ---AG
|
// querying each possibly file type. Meh. ---AG
|
||||||
@ -324,7 +325,7 @@ impl DirEntryRaw {
|
|||||||
) -> Result<DirEntryRaw, Error> {
|
) -> Result<DirEntryRaw, Error> {
|
||||||
let ty = ent.file_type().map_err(|err| {
|
let ty = ent.file_type().map_err(|err| {
|
||||||
let err = Error::Io(io::Error::from(err)).with_path(ent.path());
|
let err = Error::Io(io::Error::from(err)).with_path(ent.path());
|
||||||
Error::WithDepth { depth: depth, err: Box::new(err) }
|
Error::WithDepth { depth, err: Box::new(err) }
|
||||||
})?;
|
})?;
|
||||||
DirEntryRaw::from_entry_os(depth, ent, ty)
|
DirEntryRaw::from_entry_os(depth, ent, ty)
|
||||||
}
|
}
|
||||||
@ -337,13 +338,13 @@ impl DirEntryRaw {
|
|||||||
) -> Result<DirEntryRaw, Error> {
|
) -> Result<DirEntryRaw, Error> {
|
||||||
let md = ent.metadata().map_err(|err| {
|
let md = ent.metadata().map_err(|err| {
|
||||||
let err = Error::Io(io::Error::from(err)).with_path(ent.path());
|
let err = Error::Io(io::Error::from(err)).with_path(ent.path());
|
||||||
Error::WithDepth { depth: depth, err: Box::new(err) }
|
Error::WithDepth { depth, err: Box::new(err) }
|
||||||
})?;
|
})?;
|
||||||
Ok(DirEntryRaw {
|
Ok(DirEntryRaw {
|
||||||
path: ent.path(),
|
path: ent.path(),
|
||||||
ty: ty,
|
ty,
|
||||||
follow_link: false,
|
follow_link: false,
|
||||||
depth: depth,
|
depth,
|
||||||
metadata: md,
|
metadata: md,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -358,9 +359,9 @@ impl DirEntryRaw {
|
|||||||
|
|
||||||
Ok(DirEntryRaw {
|
Ok(DirEntryRaw {
|
||||||
path: ent.path(),
|
path: ent.path(),
|
||||||
ty: ty,
|
ty,
|
||||||
follow_link: false,
|
follow_link: false,
|
||||||
depth: depth,
|
depth,
|
||||||
ino: ent.ino(),
|
ino: ent.ino(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -391,7 +392,7 @@ impl DirEntryRaw {
|
|||||||
path: pb,
|
path: pb,
|
||||||
ty: md.file_type(),
|
ty: md.file_type(),
|
||||||
follow_link: link,
|
follow_link: link,
|
||||||
depth: depth,
|
depth,
|
||||||
metadata: md,
|
metadata: md,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -410,7 +411,7 @@ impl DirEntryRaw {
|
|||||||
path: pb,
|
path: pb,
|
||||||
ty: md.file_type(),
|
ty: md.file_type(),
|
||||||
follow_link: link,
|
follow_link: link,
|
||||||
depth: depth,
|
depth,
|
||||||
ino: md.ino(),
|
ino: md.ino(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -494,17 +495,15 @@ pub struct WalkBuilder {
|
|||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
enum Sorter {
|
enum Sorter {
|
||||||
ByName(
|
ByName(Arc<dyn Fn(&OsStr, &OsStr) -> Ordering + Send + Sync + 'static>),
|
||||||
Arc<dyn Fn(&OsStr, &OsStr) -> cmp::Ordering + Send + Sync + 'static>,
|
ByPath(Arc<dyn Fn(&Path, &Path) -> Ordering + Send + Sync + 'static>),
|
||||||
),
|
|
||||||
ByPath(Arc<dyn Fn(&Path, &Path) -> cmp::Ordering + Send + Sync + 'static>),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct Filter(Arc<dyn Fn(&DirEntry) -> bool + Send + Sync + 'static>);
|
struct Filter(Arc<dyn Fn(&DirEntry) -> bool + Send + Sync + 'static>);
|
||||||
|
|
||||||
impl fmt::Debug for WalkBuilder {
|
impl std::fmt::Debug for WalkBuilder {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
f.debug_struct("WalkBuilder")
|
f.debug_struct("WalkBuilder")
|
||||||
.field("paths", &self.paths)
|
.field("paths", &self.paths)
|
||||||
.field("ig_builder", &self.ig_builder)
|
.field("ig_builder", &self.ig_builder)
|
||||||
@ -578,7 +577,7 @@ impl WalkBuilder {
|
|||||||
.into_iter();
|
.into_iter();
|
||||||
let ig_root = self.ig_builder.build();
|
let ig_root = self.ig_builder.build();
|
||||||
Walk {
|
Walk {
|
||||||
its: its,
|
its,
|
||||||
it: None,
|
it: None,
|
||||||
ig_root: ig_root.clone(),
|
ig_root: ig_root.clone(),
|
||||||
ig: ig_root.clone(),
|
ig: ig_root.clone(),
|
||||||
@ -828,7 +827,7 @@ impl WalkBuilder {
|
|||||||
/// Note that this is not used in the parallel iterator.
|
/// Note that this is not used in the parallel iterator.
|
||||||
pub fn sort_by_file_path<F>(&mut self, cmp: F) -> &mut WalkBuilder
|
pub fn sort_by_file_path<F>(&mut self, cmp: F) -> &mut WalkBuilder
|
||||||
where
|
where
|
||||||
F: Fn(&Path, &Path) -> cmp::Ordering + Send + Sync + 'static,
|
F: Fn(&Path, &Path) -> Ordering + Send + Sync + 'static,
|
||||||
{
|
{
|
||||||
self.sorter = Some(Sorter::ByPath(Arc::new(cmp)));
|
self.sorter = Some(Sorter::ByPath(Arc::new(cmp)));
|
||||||
self
|
self
|
||||||
@ -847,7 +846,7 @@ impl WalkBuilder {
|
|||||||
/// Note that this is not used in the parallel iterator.
|
/// Note that this is not used in the parallel iterator.
|
||||||
pub fn sort_by_file_name<F>(&mut self, cmp: F) -> &mut WalkBuilder
|
pub fn sort_by_file_name<F>(&mut self, cmp: F) -> &mut WalkBuilder
|
||||||
where
|
where
|
||||||
F: Fn(&OsStr, &OsStr) -> cmp::Ordering + Send + Sync + 'static,
|
F: Fn(&OsStr, &OsStr) -> Ordering + Send + Sync + 'static,
|
||||||
{
|
{
|
||||||
self.sorter = Some(Sorter::ByName(Arc::new(cmp)));
|
self.sorter = Some(Sorter::ByName(Arc::new(cmp)));
|
||||||
self
|
self
|
||||||
@ -911,7 +910,7 @@ impl WalkBuilder {
|
|||||||
/// ignore files like `.gitignore` are respected. The precise matching rules
|
/// ignore files like `.gitignore` are respected. The precise matching rules
|
||||||
/// and precedence is explained in the documentation for `WalkBuilder`.
|
/// and precedence is explained in the documentation for `WalkBuilder`.
|
||||||
pub struct Walk {
|
pub struct Walk {
|
||||||
its: vec::IntoIter<(PathBuf, Option<WalkEventIter>)>,
|
its: std::vec::IntoIter<(PathBuf, Option<WalkEventIter>)>,
|
||||||
it: Option<WalkEventIter>,
|
it: Option<WalkEventIter>,
|
||||||
ig_root: Ignore,
|
ig_root: Ignore,
|
||||||
ig: Ignore,
|
ig: Ignore,
|
||||||
@ -1040,7 +1039,7 @@ impl Iterator for Walk {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FusedIterator for Walk {}
|
impl std::iter::FusedIterator for Walk {}
|
||||||
|
|
||||||
/// WalkEventIter transforms a WalkDir iterator into an iterator that more
|
/// WalkEventIter transforms a WalkDir iterator into an iterator that more
|
||||||
/// accurately describes the directory tree. Namely, it emits events that are
|
/// accurately describes the directory tree. Namely, it emits events that are
|
||||||
@ -1188,7 +1187,7 @@ impl<'s> ParallelVisitor for FnVisitorImp<'s> {
|
|||||||
///
|
///
|
||||||
/// Unlike `Walk`, this uses multiple threads for traversing a directory.
|
/// Unlike `Walk`, this uses multiple threads for traversing a directory.
|
||||||
pub struct WalkParallel {
|
pub struct WalkParallel {
|
||||||
paths: vec::IntoIter<PathBuf>,
|
paths: std::vec::IntoIter<PathBuf>,
|
||||||
ig_root: Ignore,
|
ig_root: Ignore,
|
||||||
max_filesize: Option<u64>,
|
max_filesize: Option<u64>,
|
||||||
max_depth: Option<usize>,
|
max_depth: Option<usize>,
|
||||||
@ -1268,9 +1267,9 @@ impl WalkParallel {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
stack.push(Message::Work(Work {
|
stack.push(Message::Work(Work {
|
||||||
dent: dent,
|
dent,
|
||||||
ignore: self.ig_root.clone(),
|
ignore: self.ig_root.clone(),
|
||||||
root_device: root_device,
|
root_device,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
// ... but there's no need to start workers if we don't need them.
|
// ... but there's no need to start workers if we don't need them.
|
||||||
@ -1408,7 +1407,7 @@ impl Stack {
|
|||||||
// on wide directories with a lot of gitignores is disastrous (for
|
// on wide directories with a lot of gitignores is disastrous (for
|
||||||
// example, searching a directory tree containing all of crates.io).
|
// example, searching a directory tree containing all of crates.io).
|
||||||
let deques: Vec<Deque<Message>> =
|
let deques: Vec<Deque<Message>> =
|
||||||
iter::repeat_with(Deque::new_lifo).take(threads).collect();
|
std::iter::repeat_with(Deque::new_lifo).take(threads).collect();
|
||||||
let stealers = Arc::<[Stealer<Message>]>::from(
|
let stealers = Arc::<[Stealer<Message>]>::from(
|
||||||
deques.iter().map(Deque::stealer).collect::<Vec<_>>(),
|
deques.iter().map(Deque::stealer).collect::<Vec<_>>(),
|
||||||
);
|
);
|
||||||
@ -1707,7 +1706,8 @@ impl<'s> Worker<'s> {
|
|||||||
// CPU waiting, we let the thread sleep for a bit. In
|
// CPU waiting, we let the thread sleep for a bit. In
|
||||||
// general, this tends to only occur once the search is
|
// general, this tends to only occur once the search is
|
||||||
// approaching termination.
|
// approaching termination.
|
||||||
thread::sleep(Duration::from_millis(1));
|
let dur = std::time::Duration::from_millis(1);
|
||||||
|
std::thread::sleep(dur);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1716,22 +1716,22 @@ impl<'s> Worker<'s> {
|
|||||||
|
|
||||||
/// Indicates that all workers should quit immediately.
|
/// Indicates that all workers should quit immediately.
|
||||||
fn quit_now(&self) {
|
fn quit_now(&self) {
|
||||||
self.quit_now.store(true, Ordering::SeqCst);
|
self.quit_now.store(true, AtomicOrdering::SeqCst);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if this worker should quit immediately.
|
/// Returns true if this worker should quit immediately.
|
||||||
fn is_quit_now(&self) -> bool {
|
fn is_quit_now(&self) -> bool {
|
||||||
self.quit_now.load(Ordering::SeqCst)
|
self.quit_now.load(AtomicOrdering::SeqCst)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the number of pending jobs.
|
/// Returns the number of pending jobs.
|
||||||
fn num_pending(&self) -> usize {
|
fn num_pending(&self) -> usize {
|
||||||
self.num_pending.load(Ordering::SeqCst)
|
self.num_pending.load(AtomicOrdering::SeqCst)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Send work.
|
/// Send work.
|
||||||
fn send(&self, work: Work) {
|
fn send(&self, work: Work) {
|
||||||
self.num_pending.fetch_add(1, Ordering::SeqCst);
|
self.num_pending.fetch_add(1, AtomicOrdering::SeqCst);
|
||||||
self.stack.push(Message::Work(work));
|
self.stack.push(Message::Work(work));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1747,7 +1747,7 @@ impl<'s> Worker<'s> {
|
|||||||
|
|
||||||
/// Signal that work has been finished.
|
/// Signal that work has been finished.
|
||||||
fn work_done(&self) {
|
fn work_done(&self) {
|
||||||
self.num_pending.fetch_sub(1, Ordering::SeqCst);
|
self.num_pending.fetch_sub(1, AtomicOrdering::SeqCst);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user