Replace std FileType with our own (serde-able) enum

This commit is contained in:
Félix Saparelli 2021-10-20 01:18:43 +13:00
parent 401437784d
commit 6671863f2f
No known key found for this signature in database
GPG key ID: B948C4BAE44FC474
4 changed files with 57 additions and 30 deletions

View file

@ -9,7 +9,6 @@
use std::{
collections::HashMap,
fmt,
fs::FileType,
path::{Path, PathBuf},
process::ExitStatus,
};
@ -54,6 +53,7 @@ pub enum Tag {
Signal(MainSignal),
/// The event is about the subprocess exiting.
// TODO: replace ExitStatus with something we can de/serialize.
ProcessCompletion(Option<ExitStatus>),
}
@ -71,6 +71,51 @@ impl Tag {
}
}
/// The type of a file.
///
/// This is a simplification of the [`std::fs::FileType`] type, which is not constructable and may
/// differ on different platforms.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[non_exhaustive]
pub enum FileType {
/// A regular file.
File,
/// A directory.
Dir,
/// A symbolic link.
Symlink,
/// Something else.
Other,
}
impl From<std::fs::FileType> for FileType {
fn from(ft: std::fs::FileType) -> Self {
if ft.is_file() {
Self::File
} else if ft.is_dir() {
Self::Dir
} else if ft.is_symlink() {
Self::Symlink
} else {
Self::Other
}
}
}
impl fmt::Display for FileType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::File => write!(f, "file"),
Self::Dir => write!(f, "dir"),
Self::Symlink => write!(f, "symlink"),
Self::Other => write!(f, "other"),
}
}
}
/// The general origin of the event.
///
/// This is set by the event source. Note that not all of these are currently used.
@ -159,19 +204,7 @@ impl fmt::Display for Event {
Tag::Path { path, file_type } => {
write!(f, " path={}", path.display())?;
if let Some(ft) = file_type {
write!(
f,
" filetype={}",
if ft.is_file() {
"file"
} else if ft.is_dir() {
"dir"
} else if ft.is_symlink() {
"symlink"
} else {
"special"
}
)?;
write!(f, " filetype={}", ft)?;
}
}
Tag::FileEventKind(kind) => write!(f, " kind={:?}", kind)?,

View file

@ -8,7 +8,7 @@ use tokio::fs::read_to_string;
use tracing::{debug, trace};
use crate::error::RuntimeError;
use crate::event::Event;
use crate::event::{Event, FileType};
use crate::filter::Filterer;
use crate::ignore_files::IgnoreFile;
@ -98,7 +98,9 @@ impl Filterer for GlobsetFilterer {
/// This implementation never errors.
fn check_event(&self, event: &Event) -> Result<bool, RuntimeError> {
for (path, file_type) in event.paths() {
let is_dir = file_type.map(|t| t.is_dir()).unwrap_or(false);
let is_dir = file_type
.map(|t| matches!(t, FileType::Dir))
.unwrap_or(false);
if self.ignores.matched(path, is_dir).is_ignore() {
trace!(?path, "ignored by globset ignore");

View file

@ -13,7 +13,7 @@ use tracing::{debug, trace, warn};
use unicase::UniCase;
use crate::error::RuntimeError;
use crate::event::{Event, Tag};
use crate::event::{Event, FileType, Tag};
use crate::filter::tagged::error::TaggedFiltererError;
use crate::filter::Filterer;
use crate::ignore_files::IgnoreFile;
@ -131,7 +131,7 @@ impl TaggedFilterer {
let mut tag_match = true;
if let (Matcher::Path, Tag::Path { path, file_type }) = (matcher, tag) {
let is_dir = file_type.map_or(false, |ft| ft.is_dir());
let is_dir = file_type.map_or(false, |ft| matches!(ft, FileType::Dir));
let gc = self.glob_compiled.borrow();
if let Some(igs) = gc.as_ref() {
@ -311,15 +311,7 @@ impl TaggedFilterer {
..
},
Matcher::FileType,
) => filter.matches(if ft.is_dir() {
"dir"
} else if ft.is_file() {
"file"
} else if ft.is_symlink() {
"symlink"
} else {
"special"
}),
) => filter.matches(ft.to_string()),
(Tag::FileEventKind(kind), Matcher::FileEventKind) => {
filter.matches(format!("{:?}", kind))
}
@ -588,8 +580,8 @@ pub enum Matcher {
///
/// This is not guaranteed to be present for every filesystem event.
///
/// It can be any of these values: `file`, `dir`, `symlink`, `special`. That last one means
/// "not any of the first three," it does not mean "a special file" as defined by the OS.
/// It can be any of these values: `file`, `dir`, `symlink`, `other`. That last one means
/// "not any of the first three."
FileType,
/// The [`EventKind`][notify::event::EventKind] of a filesystem event.

View file

@ -285,7 +285,7 @@ fn process_event(
for path in nev.paths {
// possibly pull file_type from whatever notify (or the native driver) returns?
tags.push(Tag::Path {
file_type: metadata(&path).ok().map(|m| m.file_type()),
file_type: metadata(&path).ok().map(|m| m.file_type().into()),
path: dunce::canonicalize(path)?,
});
}