1#![cfg_attr(docsrs, feature(doc_cfg))]
7#![cfg_attr(feature = "doc", doc = document_features::document_features!())]
8#![cfg_attr(test, feature(assert_matches))]
9#![feature(sync_unsafe_cell)]
10use std::path::Path;
11
12use anyhow::{Context, bail};
13use ib_shell_item::path::ShellPath;
14
15#[cfg(feature = "hook")]
16pub mod hook;
17pub mod workspace;
18
19pub trait OpenVerb: Send + Sync {
20 fn handle(&self, path: &Path) -> Option<anyhow::Result<()>>;
21
22 fn handle_shell(&self, path: &ShellPath) -> Option<anyhow::Result<()>> {
23 self.handle(&path.to_file_path().ok()?)
24 }
25}
26
27pub fn open_verbs(path: &ShellPath, verbs: &[Box<dyn OpenVerb>]) -> Option<anyhow::Result<()>> {
28 for verb in verbs {
29 if let Some(result) = verb.handle_shell(path) {
30 return Some(result);
31 }
32 }
33 None
34}
35
36pub fn open(path: &ShellPath, verbs: &[Box<dyn OpenVerb>]) -> anyhow::Result<()> {
37 if let Some(r) = open_verbs(path, verbs) {
38 return r;
39 }
40 if let Ok(path) = path.to_file_path() {
41 open::that_detached(path).context("open")
42 } else {
43 bail!("TODO")
44 }
45}