Skip to main content

CommonLibrary/FileSystem/
FileWatcherProvider.rs

1//! # FileWatcherProvider Trait
2//!
3//! Defines the abstract contract for a service that registers recursive
4//! filesystem watchers backed by the host platform's native notification
5//! mechanism (inotify / FSEvents / ReadDirectoryChangesW). Watch events are
6//! streamed back to the extension host as `$fileWatcher:event` notifications
7//! so language features, TS watch-mode, HMR, and prettier-on-save all keep
8//! working without polling.
9
10use std::path::PathBuf;
11
12use async_trait::async_trait;
13
14use crate::{Environment::Environment::Environment, Error::CommonError::CommonError};
15
16/// The kind of event a watcher observed.
17#[derive(Debug, Clone, Copy, PartialEq, Eq)]
18pub enum WatchEventKind {
19	Create,
20
21	Change,
22
23	Delete,
24}
25
26impl WatchEventKind {
27	pub fn AsString(&self) -> &'static str {
28		match self {
29			WatchEventKind::Create => "create",
30
31			WatchEventKind::Change => "change",
32
33			WatchEventKind::Delete => "delete",
34		}
35	}
36}
37
38/// A single watch event emitted from the underlying notifier.
39#[derive(Debug, Clone)]
40pub struct WatchEvent {
41	pub Handle:String,
42
43	pub Kind:WatchEventKind,
44
45	pub Path:PathBuf,
46}
47
48/// An abstract service contract for registering and cancelling recursive
49/// filesystem watchers.
50#[async_trait]
51pub trait FileWatcherProvider: Environment + Send + Sync {
52	/// Register a new watcher. `Handle` is a caller-supplied identifier
53	/// (e.g. `"watcher:7"`) that must be echoed back in every emitted event so
54	/// the extension host can route events to the right subscriber.
55	///
56	/// # Parameters
57	/// * `Handle`:      Caller-supplied watcher identifier.
58	/// * `Root`:        Absolute path of the directory to watch.
59	/// * `IsRecursive`: When `true`, observe children recursively.
60	/// * `Pattern`:     Optional glob pattern (e.g. `**/*.ts`). When present,
61	///   events whose path does not match the compiled pattern are dropped
62	///   before crossing the IPC boundary - this is critical for performance
63	///   under TypeScript-style extensions that register 10+ watchers per
64	///   activation.
65	async fn RegisterWatcher(
66		&self,
67
68		Handle:String,
69
70		Root:PathBuf,
71
72		IsRecursive:bool,
73
74		Pattern:Option<String>,
75	) -> Result<(), CommonError>;
76
77	/// Cancel a watcher registered with `RegisterWatcher`. Unknown handles
78	/// resolve to `Ok(())` so callers may safely call `dispose()` without
79	/// tracking registration state.
80	async fn UnregisterWatcher(&self, Handle:String) -> Result<(), CommonError>;
81}