#![allow(dead_code)]
use std::{
collections::HashSet,
fmt::Debug,
ops::Deref,
path::{Path, PathBuf},
sync::mpsc::{self},
thread,
time::{Duration, Instant},
};
use notify_types::event::Event;
use walkdir::WalkDir;
use crate::{
Config, Error, ErrorKind, PollWatcher, RecommendedWatcher, RecursiveMode, Watcher, WatcherKind,
};
use pretty_assertions::assert_eq;
pub use expect::*;
pub struct Receiver {
pub rx: mpsc::Receiver<Result<Event, Error>>,
pub timeout: Duration,
pub detect_changes: Option<Box<dyn Fn()>>,
pub kind: WatcherKind,
}
#[derive(Debug)]
pub enum TryRecvError {
Mpsc(mpsc::RecvTimeoutError),
Watcher(Error),
}
impl Receiver {
const DEFAULT_TIMEOUT: Duration = Duration::from_secs(1);
fn wait_expected<C: ExpectedEvents>(&mut self, mut state: ExpectedState<C>) -> WaitState {
self.detect_changes();
let mut trackers = Trackers::default();
while !state.is_empty() {
match self.try_recv() {
Ok(res) => match res {
Ok(event) => {
trackers.try_push(&event);
state.check(event)
}
Err(err) => {
let is_bad_file_descriptor = self.kind == WatcherKind::PollWatcher
&& matches!(
&err.kind,
ErrorKind::Io(io_err)
if io_err
.to_string()
.contains("Bad file descriptor (os error 9)")
);
if is_bad_file_descriptor {
continue;
}
panic!(
"Got an error from the watcher {:?}: {err:?}. State: {state:#?}",
self.kind
)
}
},
Err(e) => panic!(
"Recv error: {e:?}. Watcher: {:?}. State: {state:#?}",
self.kind
),
}
}
let remain = self.rx.try_iter().collect::<Vec<_>>();
WaitState {
trackers,
received: state.into_received(),
remain,
}
}
pub fn wait_ordered_exact(
&mut self,
expected: impl IntoIterator<Item = ExpectedEvent>,
) -> WaitState {
self.wait_expected(ExpectedState::ordered(expected).disallow_unexpected())
}
pub fn wait_ordered(&mut self, expected: impl IntoIterator<Item = ExpectedEvent>) -> WaitState {
self.wait_expected(ExpectedState::ordered(expected).allow_unexpected())
}
pub fn wait_unordered_exact(
&mut self,
expected: impl IntoIterator<Item = ExpectedEvent>,
) -> WaitState {
self.wait_expected(ExpectedState::unordered(expected).disallow_unexpected())
}
pub fn wait_unordered(
&mut self,
expected: impl IntoIterator<Item = ExpectedEvent>,
) -> WaitState {
self.wait_expected(ExpectedState::unordered(expected).allow_unexpected())
}
pub fn try_recv(&mut self) -> Result<Result<Event, Error>, mpsc::RecvTimeoutError> {
self.rx.recv_timeout(self.timeout)
}
pub fn recv(&mut self) -> Event {
self.recv_result()
.unwrap_or_else(|e| panic!("Unexpected error from the watcher {:?}: {e:?}", self.kind))
}
pub fn recv_result(&mut self) -> Result<Event, Error> {
self.try_recv().unwrap_or_else(|e| match e {
mpsc::RecvTimeoutError::Timeout => panic!("Unable to wait the next event from the watcher {:?}: timeout", self.kind),
mpsc::RecvTimeoutError::Disconnected => {
panic!("Unable to wait the next event: the watcher {:?} part of the channel was disconnected", self.kind)
}
})
}
pub fn detect_changes(&self) {
if let Some(detect_changes) = self.detect_changes.as_deref() {
detect_changes()
}
}
pub fn iter(&mut self) -> impl Iterator<Item = Event> + '_ {
struct Iter<'a> {
rx: &'a mut Receiver,
}
impl Iterator for Iter<'_> {
type Item = Event;
fn next(&mut self) -> Option<Self::Item> {
self.rx
.try_recv()
.ok()
.map(|res| res.unwrap_or_else(|err| panic!("Got an error: {err:#?}")))
}
}
Iter { rx: self }
}
pub fn ensure_empty(&mut self) {
if let Ok(event) = self.rx.try_recv() {
panic!("Unexpected event was received: {event:#?}")
}
}
#[must_use]
pub fn sleep_until<F: FnMut() -> bool>(&self, check: F) -> bool {
sleep_until(check, self.timeout)
}
pub fn sleep_until_walkdir_returns_set<Q>(
&self,
root: impl AsRef<Path>,
paths: impl IntoIterator<Item = Q>,
) where
Q: AsRef<Path>,
{
let mut actual = HashSet::new();
let expected: HashSet<PathBuf> = paths
.into_iter()
.map(|p| p.as_ref().to_path_buf())
.collect();
let walkdir_set_eq = self.sleep_until(|| {
actual.clear();
WalkDir::new(root.as_ref())
.follow_links(true)
.min_depth(1)
.into_iter()
.filter_map(|v| v.ok())
.map(|v| v.into_path())
.for_each(|path| {
actual.insert(path);
});
actual == expected
});
assert!(
walkdir_set_eq,
"Walkdir returns unexpected result: {actual:?}"
)
}
pub fn sleep_until_exists(&self, path: impl AsRef<Path>) {
let path = path.as_ref();
assert!(
self.sleep_until(|| path.exists()),
"the fs entry {path:?} has still not been exist after timeout {:?}",
self.timeout
)
}
pub fn sleep_while_exists(&self, path: impl AsRef<Path>) {
let path = path.as_ref();
assert!(
self.sleep_until(|| !path.exists()),
"the fs entry {path:?} has been exist yet after timeout {:?}",
self.timeout
)
}
pub fn sleep_until_parent_contains(&self, path: impl AsRef<Path>) {
let path = path.as_ref();
let parent = path
.parent()
.expect("The path {path:?} does not have a parent");
assert!(
self.sleep_until(|| {
std::fs::read_dir(parent)
.into_iter()
.flatten()
.flatten()
.any(|r| r.path() == path)
}),
"the path {parent:?} has not contained an expected entry {:?} after timeout {:?}",
path.file_name(),
self.timeout
)
}
pub fn sleep_while_parent_contains(&self, path: impl AsRef<Path>) {
let path = path.as_ref();
let parent = path
.parent()
.expect("The path {path:?} does not have a parent");
assert!(
self.sleep_until(|| {
!std::fs::read_dir(parent)
.into_iter()
.flatten()
.flatten()
.any(|r| r.path() == path)
}),
"the path {parent:?} has contained an expected entry {:?} yet after timeout {:?}",
path.file_name(),
self.timeout
)
}
}
#[derive(Debug)]
pub struct WaitState {
received: Vec<Event>,
remain: Vec<Result<Event, Error>>,
trackers: Trackers,
}
impl WaitState {
pub fn ensure_trackers_len(self, len: usize) -> Self {
assert_eq!(
self.trackers.len(),
len,
"Unexpected cookies len. events: {:#?}",
self.received
);
self
}
pub fn ensure_no_tail(self) -> Self {
assert!(
self.remain.is_empty(),
"Unexpected events from the watcher: unexpected: {:#?}",
self.remain
);
self
}
}
#[derive(Debug)]
pub struct ChannelConfig {
timeout: Duration,
watcher_config: Config,
}
impl ChannelConfig {
pub fn with_timeout(mut self, timeout: Duration) -> Self {
self.timeout = timeout;
self
}
pub fn with_watcher_config(mut self, config: Config) -> Self {
self.watcher_config = config;
self
}
}
impl Default for ChannelConfig {
fn default() -> Self {
Self {
timeout: Receiver::DEFAULT_TIMEOUT,
watcher_config: Config::default(),
}
}
}
pub struct TestWatcher<W> {
pub watcher: W,
pub kind: WatcherKind,
}
impl<W: Watcher> TestWatcher<W> {
pub fn watch_recursively(&mut self, path: impl AsRef<Path>) {
self.watch(path, RecursiveMode::Recursive);
}
pub fn watch_nonrecursively(&mut self, path: impl AsRef<Path>) {
self.watch(path, RecursiveMode::NonRecursive);
}
pub fn watch(&mut self, path: impl AsRef<Path>, recursive_mode: RecursiveMode) {
let path = path.as_ref();
const FSEVENT_WATCH_RETRIES: usize = 5;
const FSEVENT_WATCH_RETRY_BASE_DELAY: Duration = Duration::from_millis(50);
for attempt in 0..=FSEVENT_WATCH_RETRIES {
match self.watcher.watch(path, recursive_mode) {
Ok(()) => return,
Err(err) => {
let is_transient_fsevent_start_error = self.kind == WatcherKind::Fsevent
&& matches!(
&err.kind,
ErrorKind::Generic(message)
if message == "unable to start FSEvent stream"
);
if is_transient_fsevent_start_error && attempt < FSEVENT_WATCH_RETRIES {
let _ = self.watcher.unwatch(path);
let delay_factor = 1u32 << attempt;
thread::sleep(FSEVENT_WATCH_RETRY_BASE_DELAY * delay_factor);
continue;
}
panic!("Unable to watch {path:?}: {err:#?}")
}
}
}
unreachable!("watch() retries must return or panic")
}
}
#[must_use]
pub fn sleep_until<F: FnMut() -> bool>(mut check: F, timeout: Duration) -> bool {
let start = Instant::now();
loop {
if Instant::now()
.checked_duration_since(start)
.is_some_and(|since| since > timeout)
{
return false;
}
if check() {
return true;
}
thread::sleep(Duration::from_millis(10));
}
}
pub fn channel_with_config<W: Watcher>(config: ChannelConfig) -> (TestWatcher<W>, Receiver) {
let (tx, rx) = mpsc::channel();
let watcher = W::new(tx, config.watcher_config).expect("Unable to create a watcher");
(
TestWatcher {
watcher,
kind: W::kind(),
},
Receiver {
rx,
timeout: config.timeout,
detect_changes: None,
kind: W::kind(),
},
)
}
pub fn channel<W: Watcher>() -> (TestWatcher<W>, Receiver) {
channel_with_config(Default::default())
}
pub fn recommended_channel() -> (TestWatcher<RecommendedWatcher>, Receiver) {
channel()
}
pub fn poll_watcher_channel() -> (TestWatcher<PollWatcher>, Receiver) {
let (tx, rx) = mpsc::channel();
let watcher = PollWatcher::new(
tx,
Config::default()
.with_compare_contents(true)
.with_manual_polling(),
)
.expect("Unable to create PollWatcher");
let sender = watcher.poll_sender();
let watcher = TestWatcher {
watcher,
kind: PollWatcher::kind(),
};
let rx = Receiver {
rx,
timeout: Receiver::DEFAULT_TIMEOUT,
detect_changes: Some(Box::new(move || {
sender
.send(crate::poll::PollMessage::Poll)
.expect("PollWatcher receiver part was disconnected")
})),
kind: watcher.kind,
};
(watcher, rx)
}
pub struct TestDir {
_dir: tempfile::TempDir,
path: PathBuf,
}
impl TestDir {
pub fn path(&self) -> &Path {
&self.path
}
}
impl AsRef<Path> for TestDir {
fn as_ref(&self) -> &Path {
self.path()
}
}
pub fn testdir() -> TestDir {
let dir = tempfile::tempdir().expect("Unable to create tempdir");
let path = std::fs::canonicalize(dir.path()).unwrap_or_else(|e| {
panic!(
"unable to canonicalize tempdir path {:?}: {e:?}",
dir.path()
)
});
TestDir { _dir: dir, path }
}
#[derive(Debug, Default, Clone, PartialEq, Eq)]
pub struct Trackers(Vec<usize>);
impl Trackers {
pub fn try_push(&mut self, event: &Event) -> bool {
let Some(tracker) = event.attrs.tracker() else {
return false;
};
if self.0.last() != Some(&tracker) {
self.0.push(tracker);
true
} else {
false
}
}
}
impl Deref for Trackers {
type Target = [usize];
fn deref(&self) -> &Self::Target {
&self.0
}
}
mod expect {
use std::{
collections::VecDeque,
fmt::Debug,
path::{Path, PathBuf},
};
use notify_types::event::{
AccessKind, AccessMode, CreateKind, DataChange, Event, EventKind, MetadataKind, ModifyKind,
RemoveKind, RenameMode,
};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum UnexpectedEventBehaviour {
Ignore,
Panic,
}
#[derive(Debug)]
pub struct ExpectedState<C> {
pub remain: C,
pub received: Vec<Event>,
pub unexpected_event_behaviour: UnexpectedEventBehaviour,
multiple_event: Option<Event>,
}
impl ExpectedState<Ordered> {
pub fn ordered(iter: impl IntoIterator<Item = ExpectedEvent>) -> Self {
Self::new(iter)
}
}
impl ExpectedState<Unordered> {
pub fn unordered(iter: impl IntoIterator<Item = ExpectedEvent>) -> Self {
Self::new(iter)
}
}
impl<C: ExpectedEvents + Debug> ExpectedState<C> {
pub fn new(iter: impl IntoIterator<Item = ExpectedEvent>) -> Self {
Self {
remain: iter.into_iter().collect(),
received: Default::default(),
unexpected_event_behaviour: UnexpectedEventBehaviour::Ignore,
multiple_event: None,
}
}
pub fn allow_unexpected(mut self) -> Self {
self.unexpected_event_behaviour = UnexpectedEventBehaviour::Ignore;
self
}
pub fn disallow_unexpected(mut self) -> Self {
self.unexpected_event_behaviour = UnexpectedEventBehaviour::Panic;
self
}
pub fn is_empty(&self) -> bool {
self.remain.is_empty()
}
pub fn check(&mut self, event: Event) {
let expected = self.remain.expected(&event);
if let Some(expected) = &expected {
self.multiple_event = expected.is_multiple().then(|| event.clone());
}
self.received.push(event.clone());
if let Some(multiple_event) = &self.multiple_event {
if multiple_event.kind == event.kind && multiple_event.paths == event.paths {
return;
}
}
if expected.is_none()
&& self.unexpected_event_behaviour == UnexpectedEventBehaviour::Panic
{
panic!("Unexpected event. State: {self:#?}")
}
}
pub fn into_received(self) -> Vec<Event> {
self.received
}
}
pub trait ExpectedEvents: Debug + FromIterator<ExpectedEvent> {
fn is_empty(&self) -> bool;
fn expected(&mut self, event: &Event) -> Option<ExpectedEvent>;
}
#[derive(Debug)]
pub struct Unordered(Vec<(usize, ExpectedEvent)>);
impl ExpectedEvents for Unordered {
fn is_empty(&self) -> bool {
self.0.is_empty()
}
fn expected(&mut self, event: &Event) -> Option<ExpectedEvent> {
let found_idx = self
.0
.iter()
.enumerate()
.find(|(_, (_, expected))| expected == event)
.map(|(idx, _)| idx);
match found_idx {
Some(found_idx) => {
let (_, expected) = self.0.swap_remove(found_idx);
Some(expected)
}
None => None,
}
}
}
#[derive(Debug)]
pub struct Ordered(VecDeque<ExpectedEvent>);
impl ExpectedEvents for Ordered {
fn is_empty(&self) -> bool {
self.0.is_empty()
}
fn expected(&mut self, event: &Event) -> Option<ExpectedEvent> {
loop {
match self.0.front() {
Some(expected) => {
if expected == event {
break self.0.pop_front();
} else if expected.is_optional() {
self.0.pop_front();
} else {
break None;
}
}
None => break None,
}
}
}
}
impl FromIterator<ExpectedEvent> for Unordered {
fn from_iter<T: IntoIterator<Item = ExpectedEvent>>(iter: T) -> Self {
Self(iter.into_iter().enumerate().collect())
}
}
impl FromIterator<ExpectedEvent> for Ordered {
fn from_iter<T: IntoIterator<Item = ExpectedEvent>>(iter: T) -> Self {
Self(iter.into_iter().collect())
}
}
pub fn expected(path: impl ExpectedPath) -> ExpectedEvent {
let mut event = ExpectedEvent::default();
path.add_to_event(&mut event);
event
}
pub trait ExpectedPath {
fn add_to_event(self, event: &mut ExpectedEvent);
}
impl ExpectedPath for &Path {
fn add_to_event(self, event: &mut ExpectedEvent) {
event.push_path(self.to_path_buf());
}
}
impl ExpectedPath for &PathBuf {
fn add_to_event(self, event: &mut ExpectedEvent) {
event.push_path(self.to_path_buf());
}
}
impl ExpectedPath for PathBuf {
fn add_to_event(self, event: &mut ExpectedEvent) {
event.push_path(self);
}
}
impl<const C: usize> ExpectedPath for [PathBuf; C] {
fn add_to_event(self, event: &mut ExpectedEvent) {
for path in self {
path.add_to_event(event);
}
}
}
impl<const C: usize> ExpectedPath for [&PathBuf; C] {
fn add_to_event(self, event: &mut ExpectedEvent) {
for path in self {
path.add_to_event(event);
}
}
}
impl<const C: usize> ExpectedPath for [&Path; C] {
fn add_to_event(self, event: &mut ExpectedEvent) {
for path in self {
path.add_to_event(event);
}
}
}
#[derive(Debug, Default, Clone)]
pub struct ExpectedEvent {
kind: Option<ExpectedEventKind>,
paths: Option<Vec<PathBuf>>,
tracker: Option<Option<usize>>,
multiple: bool,
optional: bool,
}
#[derive(Debug, Clone, Copy)]
enum ExpectedEventKind {
Any,
Access(Option<ExpectedAccessKind>),
Create(Option<CreateKind>),
Modify(Option<ExpectedModifyKind>),
Remove(Option<RemoveKind>),
Other,
}
impl PartialEq<EventKind> for ExpectedEventKind {
fn eq(&self, other: &EventKind) -> bool {
match self {
ExpectedEventKind::Any => matches!(other, EventKind::Any),
ExpectedEventKind::Access(expected) => {
let EventKind::Access(other) = other else {
return false;
};
expected.is_none_or(|expected| &expected == other)
}
ExpectedEventKind::Create(expected) => {
let EventKind::Create(other) = other else {
return false;
};
expected.is_none_or(|expected| &expected == other)
}
ExpectedEventKind::Modify(expected) => {
let EventKind::Modify(other) = other else {
return false;
};
expected.is_none_or(|expected| &expected == other)
}
ExpectedEventKind::Remove(expected) => {
let EventKind::Remove(other) = other else {
return false;
};
expected.is_none_or(|expected| &expected == other)
}
ExpectedEventKind::Other => matches!(other, EventKind::Other),
}
}
}
#[derive(Debug, Clone, Copy)]
enum ExpectedAccessKind {
Any,
Read,
Open(Option<AccessMode>),
Close(Option<AccessMode>),
Other,
}
impl PartialEq<AccessKind> for ExpectedAccessKind {
fn eq(&self, other: &AccessKind) -> bool {
match self {
ExpectedAccessKind::Any => matches!(other, AccessKind::Any),
ExpectedAccessKind::Read => matches!(other, AccessKind::Read),
ExpectedAccessKind::Open(expected) => {
let AccessKind::Open(other) = other else {
return false;
};
expected.is_none_or(|expected| &expected == other)
}
ExpectedAccessKind::Close(expected) => {
let AccessKind::Close(other) = other else {
return false;
};
expected.is_none_or(|expected| &expected == other)
}
ExpectedAccessKind::Other => matches!(other, AccessKind::Other),
}
}
}
#[derive(Debug, Clone, Copy)]
enum ExpectedModifyKind {
Any,
Data(Option<DataChange>),
Metadata(Option<MetadataKind>),
Name(Option<RenameMode>),
Other,
}
impl PartialEq<ModifyKind> for ExpectedModifyKind {
fn eq(&self, other: &ModifyKind) -> bool {
match self {
ExpectedModifyKind::Any => matches!(other, ModifyKind::Any),
ExpectedModifyKind::Data(expected) => {
let ModifyKind::Data(other) = other else {
return false;
};
expected.is_none_or(|expected| &expected == other)
}
ExpectedModifyKind::Metadata(expected) => {
let ModifyKind::Metadata(other) = other else {
return false;
};
expected.is_none_or(|expected| &expected == other)
}
ExpectedModifyKind::Name(expected) => {
let ModifyKind::Name(other) = other else {
return false;
};
expected.is_none_or(|expected| &expected == other)
}
ExpectedModifyKind::Other => matches!(other, ModifyKind::Other),
}
}
}
impl PartialEq<Event> for ExpectedEvent {
fn eq(&self, other: &Event) -> bool {
let Self {
kind,
paths,
tracker,
multiple: _,
optional: _,
} = self;
kind.is_none_or(|kind| kind == other.kind)
&& tracker.is_none_or(|expected| expected == other.attrs.tracker())
&& paths
.as_ref()
.is_none_or(|expected| expected == &other.paths)
}
}
impl PartialEq<ExpectedEvent> for Event {
fn eq(&self, other: &ExpectedEvent) -> bool {
other.eq(self)
}
}
macro_rules! kind {
($name: ident, $kind: expr) => {
pub fn $name(self) -> Self {
self.kind($kind)
}
};
}
#[rustfmt::skip] impl ExpectedEvent {
pub fn add_path(mut self, path: impl AsRef<Path>) -> Self {
self.push_path(path.as_ref().to_path_buf());
self
}
pub fn push_path(&mut self, path: PathBuf) {
match &mut self.paths {
Some(paths) => paths.push(path),
None => self.paths = Some(vec![path]),
}
}
pub fn without_tracker(mut self) -> Self {
self.tracker = Some(None);
self
}
pub fn tracker(mut self, tracker: usize) -> Self {
self.tracker = Some(Some(tracker));
self
}
pub fn multiple(mut self) -> Self {
self.multiple = true;
self
}
pub fn optional(mut self) -> Self {
self.optional = true;
self
}
pub fn is_multiple(&self) -> bool {
self.multiple
}
pub fn is_optional(&self) -> bool {
self.optional
}
kind!(any, ExpectedEventKind::Any);
kind!(other, ExpectedEventKind::Other);
kind!(modify, ExpectedEventKind::Modify(None));
kind!(modify_any, ExpectedEventKind::Modify(Some(ExpectedModifyKind::Any)));
kind!(modify_other,ExpectedEventKind::Modify(Some(ExpectedModifyKind::Other)));
kind!(modify_data,ExpectedEventKind::Modify(Some(ExpectedModifyKind::Data(None))));
kind!(modify_data_any, ExpectedEventKind::Modify(Some(ExpectedModifyKind::Data(Some(DataChange::Any)))));
kind!(modify_data_other, ExpectedEventKind::Modify(Some(ExpectedModifyKind::Data(Some(DataChange::Other)))));
kind!(modify_data_content, ExpectedEventKind::Modify(Some(ExpectedModifyKind::Data(Some(DataChange::Content)))));
kind!(modify_data_size, ExpectedEventKind::Modify(Some(ExpectedModifyKind::Data(Some(DataChange::Size)))));
kind!(modify_meta, ExpectedEventKind::Modify(Some(ExpectedModifyKind::Metadata(None))));
kind!(modify_meta_any, ExpectedEventKind::Modify(Some(ExpectedModifyKind::Metadata(Some(MetadataKind::Any)))));
kind!(modify_meta_other, ExpectedEventKind::Modify(Some(ExpectedModifyKind::Metadata(Some(MetadataKind::Other )))));
kind!(modify_meta_atime, ExpectedEventKind::Modify(Some(ExpectedModifyKind::Metadata(Some(MetadataKind::AccessTime )))));
kind!(modify_meta_mtime, ExpectedEventKind::Modify(Some(ExpectedModifyKind::Metadata(Some(MetadataKind::WriteTime )))));
kind!(modify_meta_owner, ExpectedEventKind::Modify(Some(ExpectedModifyKind::Metadata(Some(MetadataKind::Ownership )))));
kind!(modify_meta_ext, ExpectedEventKind::Modify(Some(ExpectedModifyKind::Metadata(Some(MetadataKind::Extended )))));
kind!(modify_meta_perm, ExpectedEventKind::Modify(Some(ExpectedModifyKind::Metadata(Some(MetadataKind::Permissions )))));
kind!(rename, ExpectedEventKind::Modify(Some(ExpectedModifyKind::Name(None))));
kind!(rename_any, ExpectedEventKind::Modify(Some(ExpectedModifyKind::Name(Some(RenameMode::Any)))));
kind!(rename_other, ExpectedEventKind::Modify(Some(ExpectedModifyKind::Name(Some(RenameMode::Other)))));
kind!(rename_from, ExpectedEventKind::Modify(Some(ExpectedModifyKind::Name(Some(RenameMode::From)))));
kind!(rename_to, ExpectedEventKind::Modify(Some(ExpectedModifyKind::Name(Some(RenameMode::To)))));
kind!(rename_both, ExpectedEventKind::Modify(Some(ExpectedModifyKind::Name(Some(RenameMode::Both)))));
kind!(create, ExpectedEventKind::Create(None));
kind!(create_any, ExpectedEventKind::Create(Some(CreateKind::Any)));
kind!(create_other, ExpectedEventKind::Create(Some(CreateKind::Other)));
kind!(create_file, ExpectedEventKind::Create(Some(CreateKind::File)));
kind!(create_folder, ExpectedEventKind::Create(Some(CreateKind::Folder)));
kind!(remove, ExpectedEventKind::Remove(None));
kind!(remove_any, ExpectedEventKind::Remove(Some(RemoveKind::Any)));
kind!(remove_other, ExpectedEventKind::Remove(Some(RemoveKind::Other)));
kind!(remove_file, ExpectedEventKind::Remove(Some(RemoveKind::File)));
kind!(remove_folder, ExpectedEventKind::Remove(Some(RemoveKind::Folder)));
kind!(access, ExpectedEventKind::Access(None));
kind!(access_any, ExpectedEventKind::Access(Some(ExpectedAccessKind::Any)));
kind!(access_other, ExpectedEventKind::Access(Some(ExpectedAccessKind::Other)));
kind!(access_read, ExpectedEventKind::Access(Some(ExpectedAccessKind::Read)));
kind!(access_open, ExpectedEventKind::Access(Some(ExpectedAccessKind::Open(None))));
kind!(access_open_any, ExpectedEventKind::Access(Some(ExpectedAccessKind::Open(Some(AccessMode::Any)))));
kind!(access_open_other, ExpectedEventKind::Access(Some(ExpectedAccessKind::Open(Some(AccessMode::Other)))));
kind!(access_open_read, ExpectedEventKind::Access(Some(ExpectedAccessKind::Open(Some(AccessMode::Read)))));
kind!(access_open_write, ExpectedEventKind::Access(Some(ExpectedAccessKind::Open(Some(AccessMode::Write)))));
kind!(access_open_execute, ExpectedEventKind::Access(Some(ExpectedAccessKind::Open(Some(AccessMode::Execute)))));
kind!(access_close, ExpectedEventKind::Access(Some(ExpectedAccessKind::Close(None))));
kind!(access_close_any, ExpectedEventKind::Access(Some(ExpectedAccessKind::Close(Some(AccessMode::Any)))));
kind!(access_close_other, ExpectedEventKind::Access(Some(ExpectedAccessKind::Close(Some(AccessMode::Other)))));
kind!(access_close_read, ExpectedEventKind::Access(Some(ExpectedAccessKind::Close(Some(AccessMode::Read)))));
kind!(access_close_write, ExpectedEventKind::Access(Some(ExpectedAccessKind::Close(Some(AccessMode::Write)))));
kind!(access_close_execute, ExpectedEventKind::Access(Some(ExpectedAccessKind::Close(Some(AccessMode::Execute)))));
fn kind(mut self, kind: ExpectedEventKind) -> Self {
self.kind = Some(kind);
self
}
}
}