Skip to main content

plat/
capabilities.rs

1// Platform service availability, shared by app commands, agent schemas and browser hosts.
2
3/// Read files through the platform's file namespace.
4pub const CAP_FILE_READ: u64 = 1 << 0;
5/// Write files through the platform's file namespace.
6pub const CAP_FILE_WRITE: u64 = 1 << 1;
7/// Confirm durable storage, rather than a temporary in-memory write.
8pub const CAP_PERSISTENT_STORAGE: u64 = 1 << 2;
9/// Exchange plain UTF-8 clipboard text.
10pub const CAP_CLIPBOARD_TEXT: u64 = 1 << 3;
11/// Exchange native/RTF/HTML rich clipboard representations.
12/// Browser hosts provide an instance-local clipboard, without OS rich-format access.
13pub const CAP_CLIPBOARD_RICH: u64 = 1 << 4;
14/// Exchange clipboard images.
15pub const CAP_CLIPBOARD_IMAGE: u64 = 1 << 5;
16/// Submit a print job through the host.
17pub const CAP_PRINT: u64 = 1 << 6;
18/// Discover fonts installed in the operating system.
19pub const CAP_SYSTEM_FONTS: u64 = 1 << 7;
20/// Load native shared libraries with the platform plugin ABI.
21pub const CAP_NATIVE_PLUGINS: u64 = 1 << 8;
22/// Connect through a user-local IPC transport after explicit activation.
23pub const CAP_LOCAL_IPC: u64 = 1 << 9;
24/// Display windows, including library windows inside a browser canvas.
25pub const CAP_WINDOWING: u64 = 1 << 10;
26/// Run parallel operating-system threads.
27pub const CAP_THREADS: u64 = 1 << 11;
28/// Install operating-system shortcuts or integrations.
29pub const CAP_SHELL_INTEGRATION: u64 = 1 << 12;
30
31/// Snapshot of services actually provided by the current host.
32#[derive(Clone, Copy, Debug, PartialEq, Eq)]
33pub struct Capabilities {
34    /// Bit set of the `CAP_*` services.
35    pub available: u64,
36}
37impl Capabilities {
38    /// Whether every requested service is available.
39    pub const fn supports(self, required: u64) -> bool {
40        self.available & required == required
41    }
42    /// A concrete explanation for the first missing service, or no limitation.
43    pub fn unavailable_reason(self, required: u64) -> Option<&'static str> {
44        let missing = required & !self.available;
45        let reasons = [
46            (CAP_FILE_READ, "This host has not granted file access."),
47            (CAP_FILE_WRITE, "This host has not granted file write access."),
48            (CAP_PERSISTENT_STORAGE, "Persistent storage has not been granted or confirmed."),
49            (CAP_CLIPBOARD_TEXT, "Clipboard text access is not available or has not been granted."),
50            (CAP_CLIPBOARD_RICH, "This host cannot exchange rich clipboard formats."),
51            (CAP_CLIPBOARD_IMAGE, "This host cannot exchange clipboard images."),
52            (CAP_PRINT, "Printing is not available on this host."),
53            (CAP_SYSTEM_FONTS, "Installed system fonts are not accessible on this host."),
54            (CAP_NATIVE_PLUGINS, "Native DLL/SO plugins cannot run on this platform."),
55            (CAP_LOCAL_IPC, "Local IPC requires a native host or an explicitly connected browser bridge."),
56            (CAP_WINDOWING, "No window surface is available."),
57            (CAP_THREADS, "This host uses sequential execution instead of operating-system threads."),
58            (CAP_SHELL_INTEGRATION, "Operating-system installation is unavailable on this host."),
59        ];
60        reasons.iter().find(|(flag, _)| missing & flag != 0).map(|(_, reason)| *reason)
61            .or(if missing != 0 { Some("An unknown platform capability was requested.") } else { None })
62    }
63}
64
65/// Current native service set, less what the app's permissions leave out (policy.rs).
66/// Browser permissions are supplied by its host adapter.
67#[cfg(not(any(target_arch = "wasm32", target_os = "android")))]
68pub fn capabilities() -> Capabilities {
69    Capabilities { available: ((1 << 13) - 1) & crate::policy::cap_mask() }
70}