1 | // This file is dual-licensed under the Artistic License 2.0 as per the
|
2 | // LICENSE.ARTISTIC file, and the Creative Commons Zero 1.0 license.
|
3 | //! The `Event` type and the hierarchical `EventKind` descriptor.
|
4 |
|
5 | use std::{
|
6 | fmt,
|
7 | hash::{Hash, Hasher},
|
8 | path::PathBuf,
|
9 | };
|
10 |
|
11 | #[cfg (feature = "serde" )]
|
12 | use serde::{Deserialize, Serialize};
|
13 |
|
14 | /// An event describing open or close operations on files.
|
15 | #[derive (Clone, Copy, Debug, Eq, Hash, PartialEq)]
|
16 | #[cfg_attr (feature = "serde" , derive(Serialize, Deserialize))]
|
17 | #[cfg_attr (feature = "serde" , serde(rename_all = "kebab-case" ))]
|
18 | pub enum AccessMode {
|
19 | /// The catch-all case, to be used when the specific kind of event is unknown.
|
20 | Any,
|
21 |
|
22 | /// An event emitted when the file is executed, or the folder opened.
|
23 | Execute,
|
24 |
|
25 | /// An event emitted when the file is opened for reading.
|
26 | Read,
|
27 |
|
28 | /// An event emitted when the file is opened for writing.
|
29 | Write,
|
30 |
|
31 | /// An event which specific kind is known but cannot be represented otherwise.
|
32 | Other,
|
33 | }
|
34 |
|
35 | /// An event describing non-mutating access operations on files.
|
36 | #[derive (Clone, Copy, Debug, Eq, Hash, PartialEq)]
|
37 | #[cfg_attr (feature = "serde" , derive(Serialize, Deserialize))]
|
38 | #[cfg_attr (feature = "serde" , serde(tag = "kind" , content = "mode" ))]
|
39 | #[cfg_attr (feature = "serde" , serde(rename_all = "kebab-case" ))]
|
40 | pub enum AccessKind {
|
41 | /// The catch-all case, to be used when the specific kind of event is unknown.
|
42 | Any,
|
43 |
|
44 | /// An event emitted when the file is read.
|
45 | Read,
|
46 |
|
47 | /// An event emitted when the file, or a handle to the file, is opened.
|
48 | Open(AccessMode),
|
49 |
|
50 | /// An event emitted when the file, or a handle to the file, is closed.
|
51 | Close(AccessMode),
|
52 |
|
53 | /// An event which specific kind is known but cannot be represented otherwise.
|
54 | Other,
|
55 | }
|
56 |
|
57 | /// An event describing creation operations on files.
|
58 | #[derive (Clone, Copy, Debug, Eq, Hash, PartialEq)]
|
59 | #[cfg_attr (feature = "serde" , derive(Serialize, Deserialize))]
|
60 | #[cfg_attr (feature = "serde" , serde(tag = "kind" ))]
|
61 | #[cfg_attr (feature = "serde" , serde(rename_all = "kebab-case" ))]
|
62 | pub enum CreateKind {
|
63 | /// The catch-all case, to be used when the specific kind of event is unknown.
|
64 | Any,
|
65 |
|
66 | /// An event which results in the creation of a file.
|
67 | File,
|
68 |
|
69 | /// An event which results in the creation of a folder.
|
70 | Folder,
|
71 |
|
72 | /// An event which specific kind is known but cannot be represented otherwise.
|
73 | Other,
|
74 | }
|
75 |
|
76 | /// An event emitted when the data content of a file is changed.
|
77 | #[derive (Clone, Copy, Debug, Eq, Hash, PartialEq)]
|
78 | #[cfg_attr (feature = "serde" , derive(Serialize, Deserialize))]
|
79 | #[cfg_attr (feature = "serde" , serde(rename_all = "kebab-case" ))]
|
80 | pub enum DataChange {
|
81 | /// The catch-all case, to be used when the specific kind of event is unknown.
|
82 | Any,
|
83 |
|
84 | /// An event emitted when the size of the data is changed.
|
85 | Size,
|
86 |
|
87 | /// An event emitted when the content of the data is changed.
|
88 | Content,
|
89 |
|
90 | /// An event which specific kind is known but cannot be represented otherwise.
|
91 | Other,
|
92 | }
|
93 |
|
94 | /// An event emitted when the metadata of a file or folder is changed.
|
95 | #[derive (Clone, Copy, Debug, Eq, Hash, PartialEq)]
|
96 | #[cfg_attr (feature = "serde" , derive(Serialize, Deserialize))]
|
97 | #[cfg_attr (feature = "serde" , serde(rename_all = "kebab-case" ))]
|
98 | pub enum MetadataKind {
|
99 | /// The catch-all case, to be used when the specific kind of event is unknown.
|
100 | Any,
|
101 |
|
102 | /// An event emitted when the access time of the file or folder is changed.
|
103 | AccessTime,
|
104 |
|
105 | /// An event emitted when the write or modify time of the file or folder is changed.
|
106 | WriteTime,
|
107 |
|
108 | /// An event emitted when the permissions of the file or folder are changed.
|
109 | Permissions,
|
110 |
|
111 | /// An event emitted when the ownership of the file or folder is changed.
|
112 | Ownership,
|
113 |
|
114 | /// An event emitted when an extended attribute of the file or folder is changed.
|
115 | ///
|
116 | /// If the extended attribute's name or type is known, it should be provided in the
|
117 | /// `Info` event attribute.
|
118 | Extended,
|
119 |
|
120 | /// An event which specific kind is known but cannot be represented otherwise.
|
121 | Other,
|
122 | }
|
123 |
|
124 | /// An event emitted when the name of a file or folder is changed.
|
125 | #[derive (Clone, Copy, Debug, Eq, Hash, PartialEq)]
|
126 | #[cfg_attr (feature = "serde" , derive(Serialize, Deserialize))]
|
127 | #[cfg_attr (feature = "serde" , serde(rename_all = "kebab-case" ))]
|
128 | pub enum RenameMode {
|
129 | /// The catch-all case, to be used when the specific kind of event is unknown.
|
130 | Any,
|
131 |
|
132 | /// An event emitted on the file or folder resulting from a rename.
|
133 | To,
|
134 |
|
135 | /// An event emitted on the file or folder that was renamed.
|
136 | From,
|
137 |
|
138 | /// A single event emitted with both the `From` and `To` paths.
|
139 | ///
|
140 | /// This event should be emitted when both source and target are known. The paths should be
|
141 | /// provided in this exact order (from, to).
|
142 | Both,
|
143 |
|
144 | /// An event which specific kind is known but cannot be represented otherwise.
|
145 | Other,
|
146 | }
|
147 |
|
148 | /// An event describing mutation of content, name, or metadata.
|
149 | #[derive (Clone, Copy, Debug, Eq, Hash, PartialEq)]
|
150 | #[cfg_attr (feature = "serde" , derive(Serialize, Deserialize))]
|
151 | #[cfg_attr (feature = "serde" , serde(tag = "kind" , content = "mode" ))]
|
152 | #[cfg_attr (feature = "serde" , serde(rename_all = "kebab-case" ))]
|
153 | pub enum ModifyKind {
|
154 | /// The catch-all case, to be used when the specific kind of event is unknown.
|
155 | Any,
|
156 |
|
157 | /// An event emitted when the data content of a file is changed.
|
158 | Data(DataChange),
|
159 |
|
160 | /// An event emitted when the metadata of a file or folder is changed.
|
161 | Metadata(MetadataKind),
|
162 |
|
163 | /// An event emitted when the name of a file or folder is changed.
|
164 | #[cfg_attr (feature = "serde" , serde(rename = "rename" ))]
|
165 | Name(RenameMode),
|
166 |
|
167 | /// An event which specific kind is known but cannot be represented otherwise.
|
168 | Other,
|
169 | }
|
170 |
|
171 | /// An event describing removal operations on files.
|
172 | #[derive (Clone, Copy, Debug, Eq, Hash, PartialEq)]
|
173 | #[cfg_attr (feature = "serde" , derive(Serialize, Deserialize))]
|
174 | #[cfg_attr (feature = "serde" , serde(tag = "kind" ))]
|
175 | #[cfg_attr (feature = "serde" , serde(rename_all = "kebab-case" ))]
|
176 | pub enum RemoveKind {
|
177 | /// The catch-all case, to be used when the specific kind of event is unknown.
|
178 | Any,
|
179 |
|
180 | /// An event emitted when a file is removed.
|
181 | File,
|
182 |
|
183 | /// An event emitted when a folder is removed.
|
184 | Folder,
|
185 |
|
186 | /// An event which specific kind is known but cannot be represented otherwise.
|
187 | Other,
|
188 | }
|
189 |
|
190 | /// Top-level event kind.
|
191 | ///
|
192 | /// This is arguably the most important classification for events. All subkinds below this one
|
193 | /// represent details that may or may not be available for any particular backend, but most tools
|
194 | /// and Notify systems will only care about which of these four general kinds an event is about.
|
195 | #[derive (Clone, Copy, Debug, Eq, Hash, PartialEq)]
|
196 | #[cfg_attr (feature = "serde" , derive(Serialize, Deserialize))]
|
197 | #[cfg_attr (feature = "serde" , serde(rename_all = "kebab-case" ))]
|
198 | pub enum EventKind {
|
199 | /// The catch-all event kind, for unsupported/unknown events.
|
200 | ///
|
201 | /// This variant should be used as the "else" case when mapping native kernel bitmasks or
|
202 | /// bitmaps, such that if the mask is ever extended with new event types the backend will not
|
203 | /// gain bugs due to not matching new unknown event types.
|
204 | ///
|
205 | /// This variant is also the default variant used when Notify is in "imprecise" mode.
|
206 | Any,
|
207 |
|
208 | /// An event describing non-mutating access operations on files.
|
209 | ///
|
210 | /// This event is about opening and closing file handles, as well as executing files, and any
|
211 | /// other such event that is about accessing files, folders, or other structures rather than
|
212 | /// mutating them.
|
213 | ///
|
214 | /// Only some platforms are capable of generating these.
|
215 | Access(AccessKind),
|
216 |
|
217 | /// An event describing creation operations on files.
|
218 | ///
|
219 | /// This event is about the creation of files, folders, or other structures but not about e.g.
|
220 | /// writing new content into them.
|
221 | Create(CreateKind),
|
222 |
|
223 | /// An event describing mutation of content, name, or metadata.
|
224 | ///
|
225 | /// This event is about the mutation of files', folders', or other structures' content, name
|
226 | /// (path), or associated metadata (attributes).
|
227 | Modify(ModifyKind),
|
228 |
|
229 | /// An event describing removal operations on files.
|
230 | ///
|
231 | /// This event is about the removal of files, folders, or other structures but not e.g. erasing
|
232 | /// content from them. This may also be triggered for renames/moves that move files _out of the
|
233 | /// watched subpath_.
|
234 | ///
|
235 | /// Some editors also trigger Remove events when saving files as they may opt for removing (or
|
236 | /// renaming) the original then creating a new file in-place.
|
237 | Remove(RemoveKind),
|
238 |
|
239 | /// An event not fitting in any of the above four categories.
|
240 | ///
|
241 | /// This may be used for meta-events about the watch itself.
|
242 | Other,
|
243 | }
|
244 |
|
245 | impl EventKind {
|
246 | /// Indicates whether an event is an Access variant.
|
247 | pub fn is_access(&self) -> bool {
|
248 | matches!(self, EventKind::Access(_))
|
249 | }
|
250 |
|
251 | /// Indicates whether an event is a Create variant.
|
252 | pub fn is_create(&self) -> bool {
|
253 | matches!(self, EventKind::Create(_))
|
254 | }
|
255 |
|
256 | /// Indicates whether an event is a Modify variant.
|
257 | pub fn is_modify(&self) -> bool {
|
258 | matches!(self, EventKind::Modify(_))
|
259 | }
|
260 |
|
261 | /// Indicates whether an event is a Remove variant.
|
262 | pub fn is_remove(&self) -> bool {
|
263 | matches!(self, EventKind::Remove(_))
|
264 | }
|
265 |
|
266 | /// Indicates whether an event is an Other variant.
|
267 | pub fn is_other(&self) -> bool {
|
268 | matches!(self, EventKind::Other)
|
269 | }
|
270 | }
|
271 |
|
272 | impl Default for EventKind {
|
273 | fn default() -> Self {
|
274 | EventKind::Any
|
275 | }
|
276 | }
|
277 |
|
278 | /// Notify event.
|
279 | ///
|
280 | /// You might want to check [`Event::need_rescan`] to make sure no event was missed before you
|
281 | /// received this one.
|
282 | #[derive (Clone)]
|
283 | #[cfg_attr (feature = "serde" , derive(Serialize, Deserialize))]
|
284 | pub struct Event {
|
285 | /// Kind or type of the event.
|
286 | ///
|
287 | /// This is a hierarchy of enums describing the event as precisely as possible. All enums in
|
288 | /// the hierarchy have two variants always present, `Any` and `Other`, accompanied by one or
|
289 | /// more specific variants.
|
290 | ///
|
291 | /// `Any` should be used when more detail about the event is not known beyond the variant
|
292 | /// already selected. For example, `AccessMode::Any` means a file has been accessed, but that's
|
293 | /// all we know.
|
294 | ///
|
295 | /// `Other` should be used when more detail _is_ available, but cannot be encoded as one of the
|
296 | /// defined variants. When specifying `Other`, the event attributes should contain an `Info`
|
297 | /// entry with a short string identifying this detail. That string is to be considered part of
|
298 | /// the interface of the backend (i.e. a change should probably be breaking).
|
299 | ///
|
300 | /// For example, `CreateKind::Other` with an `Info("mount")` may indicate the binding of a
|
301 | /// mount. The documentation of the particular backend should indicate if any `Other` events
|
302 | /// are generated, and what their description means.
|
303 | ///
|
304 | /// The `EventKind::Any` variant should be used as the "else" case when mapping native kernel
|
305 | /// bitmasks or bitmaps, such that if the mask is ever extended with new event types the
|
306 | /// backend will not gain bugs due to not matching new unknown event types.
|
307 | #[cfg_attr (feature = "serde" , serde(rename = "type" ))]
|
308 | pub kind: EventKind,
|
309 |
|
310 | /// Paths the event is about, if known.
|
311 | ///
|
312 | /// If an event concerns two or more paths, and the paths are known at the time of event
|
313 | /// creation, they should all go in this `Vec`. Otherwise, using the `Tracker` attr may be more
|
314 | /// appropriate.
|
315 | ///
|
316 | /// The order of the paths is likely to be significant! For example, renames where both ends of
|
317 | /// the name change are known will have the "source" path first, and the "target" path last.
|
318 | pub paths: Vec<PathBuf>,
|
319 |
|
320 | // "What should be in the struct" and "what can go in the attrs" is an interesting question.
|
321 | //
|
322 | // Technically, the paths could go in the attrs. That would reduce the type size to 4 pointer
|
323 | // widths, instead of 7 like it is now. Anything 8 and below is probably good — on x64 that's
|
324 | // the size of an L1 cache line. The entire kind classification fits in 3 bytes, and an AnyMap
|
325 | // is 3 pointers. A Vec<PathBuf> is another 3 pointers.
|
326 | //
|
327 | // Type size aside, what's behind these structures? A Vec and a PathBuf is stored on the heap.
|
328 | // An AnyMap is stored on the heap. But a Vec is directly there, requiring about one access to
|
329 | // get, while retrieving anything in the AnyMap requires some accesses as overhead.
|
330 | //
|
331 | // So things that are used often should be on the struct, and things that are used more rarely
|
332 | // should go in the attrs. Additionally, arbitrary data can _only_ go in the attrs.
|
333 | //
|
334 | // The kind and the paths vie for first place on this scale, depending on how downstream wishes
|
335 | // to use the information. Everything else is secondary. So far, that's why paths live here.
|
336 | //
|
337 | // In the future, it might be possible to have more data and to benchmark things properly, so
|
338 | // the performance can be actually quantified. Also, it might turn out that I have no idea what
|
339 | // I was talking about, so the above may be discarded or reviewed. We'll see!
|
340 | //
|
341 | /// Additional attributes of the event.
|
342 | ///
|
343 | /// Arbitrary data may be added to this field, without restriction beyond the `Sync` and
|
344 | /// `Clone` properties. Some data added here is considered for comparing and hashing, but not
|
345 | /// all: at this writing this is `Tracker`, `Flag`, `Info`, and `Source`.
|
346 | #[cfg_attr (feature = "serde" , serde(default))]
|
347 | pub attrs: EventAttributes,
|
348 | }
|
349 |
|
350 | /// Additional attributes of the event.
|
351 | #[derive (Clone, Default, Debug)]
|
352 | #[cfg_attr (feature = "serde" , derive(Serialize, Deserialize))]
|
353 | pub struct EventAttributes {
|
354 | #[cfg_attr (feature = "serde" , serde(flatten))]
|
355 | inner: Option<Box<EventAttributesInner>>,
|
356 | }
|
357 |
|
358 | #[derive (Clone, Default, Debug)]
|
359 | #[cfg_attr (feature = "serde" , derive(Serialize, Deserialize))]
|
360 | struct EventAttributesInner {
|
361 | /// Tracking ID for events that are related.
|
362 | ///
|
363 | /// For events generated by backends with the `TrackRelated` capability. Those backends _may_
|
364 | /// emit events that are related to each other, and tag those with an identical "tracking id"
|
365 | /// or "cookie". The value is normalised to `usize`.
|
366 | #[cfg_attr (
|
367 | feature = "serde" ,
|
368 | serde(default, skip_serializing_if = "Option::is_none" )
|
369 | )]
|
370 | tracker: Option<usize>,
|
371 |
|
372 | /// Special Notify flag on the event.
|
373 | #[cfg_attr (
|
374 | feature = "serde" ,
|
375 | serde(default, skip_serializing_if = "Option::is_none" )
|
376 | )]
|
377 | flag: Option<Flag>,
|
378 |
|
379 | /// Additional information on the event.
|
380 | ///
|
381 | /// This is to be used for all `Other` variants of the event kind hierarchy. The variant
|
382 | /// indicates that a consumer should look into the `attrs` for an `Info` value; if that value
|
383 | /// is missing it should be considered a backend bug.
|
384 | ///
|
385 | /// This attribute may also be present for non-`Other` variants of the event kind, if doing so
|
386 | /// provides useful precision. For example, the `Modify(Metadata(Extended))` kind suggests
|
387 | /// using this attribute when information about _what_ extended metadata changed is available.
|
388 | ///
|
389 | /// This should be a short string, and changes may be considered breaking.
|
390 | #[cfg_attr (
|
391 | feature = "serde" ,
|
392 | serde(default, skip_serializing_if = "Option::is_none" )
|
393 | )]
|
394 | info: Option<String>,
|
395 |
|
396 | /// The source of the event.
|
397 | ///
|
398 | /// In most cases this should be a short string, identifying the backend unambiguously. In some
|
399 | /// cases this may be dynamically generated, but should contain a prefix to make it unambiguous
|
400 | /// between backends.
|
401 | #[cfg_attr (
|
402 | feature = "serde" ,
|
403 | serde(default, skip_serializing_if = "Option::is_none" )
|
404 | )]
|
405 | source: Option<String>,
|
406 |
|
407 | /// The process ID of the originator of the event.
|
408 | ///
|
409 | /// This attribute is experimental and, while included in Notify itself, is not considered
|
410 | /// stable or standard enough to be part of the serde, eq, hash, and debug representations.
|
411 | #[cfg_attr (
|
412 | feature = "serde" ,
|
413 | serde(default, skip_serializing, skip_deserializing)
|
414 | )]
|
415 | process_id: Option<u32>,
|
416 | }
|
417 |
|
418 | impl EventAttributes {
|
419 | /// Creates a new `EventAttributes`.
|
420 | pub fn new() -> Self {
|
421 | Self { inner: None }
|
422 | }
|
423 |
|
424 | /// Retrieves the tracker ID for an event directly, if present.
|
425 | pub fn tracker(&self) -> Option<usize> {
|
426 | self.inner.as_ref().and_then(|inner| inner.tracker)
|
427 | }
|
428 |
|
429 | /// Retrieves the Notify flag for an event directly, if present.
|
430 | pub fn flag(&self) -> Option<Flag> {
|
431 | self.inner.as_ref().and_then(|inner| inner.flag)
|
432 | }
|
433 |
|
434 | /// Retrieves the additional info for an event directly, if present.
|
435 | pub fn info(&self) -> Option<&str> {
|
436 | self.inner.as_ref().and_then(|inner| inner.info.as_deref())
|
437 | }
|
438 |
|
439 | /// Retrieves the source for an event directly, if present.
|
440 | pub fn source(&self) -> Option<&str> {
|
441 | self.inner
|
442 | .as_ref()
|
443 | .and_then(|inner| inner.source.as_deref())
|
444 | }
|
445 |
|
446 | /// The process ID of the originator of the event.
|
447 | ///
|
448 | /// This attribute is experimental and, while included in Notify itself, is not considered
|
449 | /// stable or standard enough to be part of the serde, eq, hash, and debug representations.
|
450 | pub fn process_id(&self) -> Option<u32> {
|
451 | self.inner.as_ref().and_then(|inner| inner.process_id)
|
452 | }
|
453 |
|
454 | /// Sets the tracker.
|
455 | pub fn set_tracker(&mut self, tracker: usize) {
|
456 | self.inner_mut().tracker = Some(tracker);
|
457 | }
|
458 |
|
459 | /// Sets the Notify flag onto the event.
|
460 | pub fn set_flag(&mut self, flag: Flag) {
|
461 | self.inner_mut().flag = Some(flag);
|
462 | }
|
463 |
|
464 | /// Sets additional info onto the event.
|
465 | pub fn set_info(&mut self, info: &str) {
|
466 | self.inner_mut().info = Some(info.to_string());
|
467 | }
|
468 |
|
469 | /// Sets the process id onto the event.
|
470 | pub fn set_process_id(&mut self, process_id: u32) {
|
471 | self.inner_mut().process_id = Some(process_id)
|
472 | }
|
473 |
|
474 | fn inner_mut(&mut self) -> &mut EventAttributesInner {
|
475 | self.inner
|
476 | .get_or_insert_with(|| Box::new(Default::default()))
|
477 | }
|
478 | }
|
479 |
|
480 | /// Special Notify flag on the event.
|
481 | ///
|
482 | /// This attribute is used to flag certain kinds of events that Notify either marks or generates in
|
483 | /// particular ways.
|
484 | #[derive (Clone, Copy, Debug, Eq, Hash, PartialEq)]
|
485 | #[cfg_attr (feature = "serde" , derive(Deserialize, Serialize))]
|
486 | pub enum Flag {
|
487 | /// Rescan notices are emitted by some platforms (and may also be emitted by Notify itself).
|
488 | /// They indicate either a lapse in the events or a change in the filesystem such that events
|
489 | /// received so far can no longer be relied on to represent the state of the filesystem now.
|
490 | ///
|
491 | /// An application that simply reacts to file changes may not care about this. An application
|
492 | /// that keeps an in-memory representation of the filesystem will need to care, and will need
|
493 | /// to refresh that representation directly from the filesystem.
|
494 | Rescan,
|
495 | }
|
496 |
|
497 | impl Event {
|
498 | /// Returns whether some events may have been missed. If true, you should assume any file or
|
499 | /// folder might have been modified.
|
500 | ///
|
501 | /// See [`Flag::Rescan`] for more information.
|
502 | pub fn need_rescan(&self) -> bool {
|
503 | matches!(self.flag(), Some(Flag::Rescan))
|
504 | }
|
505 | /// Retrieves the tracker ID for an event directly, if present.
|
506 | pub fn tracker(&self) -> Option<usize> {
|
507 | self.attrs.tracker()
|
508 | }
|
509 |
|
510 | /// Retrieves the Notify flag for an event directly, if present.
|
511 | pub fn flag(&self) -> Option<Flag> {
|
512 | self.attrs.flag()
|
513 | }
|
514 |
|
515 | /// Retrieves the additional info for an event directly, if present.
|
516 | pub fn info(&self) -> Option<&str> {
|
517 | self.attrs.info()
|
518 | }
|
519 |
|
520 | /// Retrieves the source for an event directly, if present.
|
521 | pub fn source(&self) -> Option<&str> {
|
522 | self.attrs.source()
|
523 | }
|
524 |
|
525 | /// Creates a new `Event` given a kind.
|
526 | pub fn new(kind: EventKind) -> Self {
|
527 | Self {
|
528 | kind,
|
529 | paths: Vec::new(),
|
530 | attrs: EventAttributes::new(),
|
531 | }
|
532 | }
|
533 |
|
534 | /// Sets the kind.
|
535 | pub fn set_kind(mut self, kind: EventKind) -> Self {
|
536 | self.kind = kind;
|
537 | self
|
538 | }
|
539 |
|
540 | /// Adds a path to the event.
|
541 | pub fn add_path(mut self, path: PathBuf) -> Self {
|
542 | self.paths.push(path);
|
543 | self
|
544 | }
|
545 |
|
546 | /// Adds a path to the event if the argument is Some.
|
547 | pub fn add_some_path(self, path: Option<PathBuf>) -> Self {
|
548 | if let Some(path) = path {
|
549 | self.add_path(path)
|
550 | } else {
|
551 | self
|
552 | }
|
553 | }
|
554 |
|
555 | /// Sets the tracker.
|
556 | pub fn set_tracker(mut self, tracker: usize) -> Self {
|
557 | self.attrs.set_tracker(tracker);
|
558 | self
|
559 | }
|
560 |
|
561 | /// Sets additional info onto the event.
|
562 | pub fn set_info(mut self, info: &str) -> Self {
|
563 | self.attrs.set_info(info);
|
564 | self
|
565 | }
|
566 |
|
567 | /// Sets the Notify flag onto the event.
|
568 | pub fn set_flag(mut self, flag: Flag) -> Self {
|
569 | self.attrs.set_flag(flag);
|
570 | self
|
571 | }
|
572 |
|
573 | /// Sets the process id onto the event.
|
574 | pub fn set_process_id(mut self, process_id: u32) -> Self {
|
575 | self.attrs.set_process_id(process_id);
|
576 | self
|
577 | }
|
578 | }
|
579 |
|
580 | impl fmt::Debug for Event {
|
581 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
582 | f&mut DebugStruct<'_, '_>.debug_struct("Event" )
|
583 | .field("kind" , &self.kind)
|
584 | .field("paths" , &self.paths)
|
585 | .field("attr:tracker" , &self.tracker())
|
586 | .field("attr:flag" , &self.flag())
|
587 | .field("attr:info" , &self.info())
|
588 | .field(name:"attr:source" , &self.source())
|
589 | .finish()
|
590 | }
|
591 | }
|
592 | impl Default for Event {
|
593 | fn default() -> Self {
|
594 | Self {
|
595 | kind: EventKind::default(),
|
596 | paths: Vec::new(),
|
597 | attrs: EventAttributes::new(),
|
598 | }
|
599 | }
|
600 | }
|
601 |
|
602 | impl Eq for Event {}
|
603 | impl PartialEq for Event {
|
604 | fn eq(&self, other: &Self) -> bool {
|
605 | self.kind.eq(&other.kind)
|
606 | && self.paths.eq(&other.paths)
|
607 | && self.tracker().eq(&other.tracker())
|
608 | && self.flag().eq(&other.flag())
|
609 | && self.info().eq(&other.info())
|
610 | && self.source().eq(&other.source())
|
611 | }
|
612 | }
|
613 |
|
614 | impl Hash for Event {
|
615 | fn hash<H: Hasher>(&self, state: &mut H) {
|
616 | self.kind.hash(state);
|
617 | self.paths.hash(state);
|
618 | self.tracker().hash(state);
|
619 | self.flag().hash(state);
|
620 | self.info().hash(state);
|
621 | self.source().hash(state);
|
622 | }
|
623 | }
|
624 | |