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}