1pub fn git(args: &[String]) -> Result<String, String> {
13 imp::git(args)
14}
15
16#[cfg(target_arch = "wasm32")]
17mod imp {
18 use crate::bindings::diffr::plugin::host;
19
20 pub(super) fn git(args: &[String]) -> Result<String, String> {
21 host::git(args)
22 }
23}
24
25#[cfg(not(target_arch = "wasm32"))]
28pub trait Host {
29 fn git(&self, args: &[String]) -> Result<String, String>;
30}
31
32#[cfg(not(target_arch = "wasm32"))]
35pub fn scope<R>(host: std::rc::Rc<dyn Host>, call: impl FnOnce() -> R) -> R {
36 imp::scope(host, call)
37}
38
39#[cfg(not(target_arch = "wasm32"))]
40mod imp {
41 use super::Host;
42 use std::cell::RefCell;
43 use std::rc::Rc;
44
45 thread_local! {
46 static CURRENT: RefCell<Option<Rc<dyn Host>>> = const { RefCell::new(None) };
47 }
48
49 struct Restore(Option<Rc<dyn Host>>);
51
52 impl Drop for Restore {
53 fn drop(&mut self) {
54 CURRENT.with(|current| *current.borrow_mut() = self.0.take());
55 }
56 }
57
58 pub(super) fn scope<R>(host: Rc<dyn Host>, call: impl FnOnce() -> R) -> R {
59 let _restore = Restore(CURRENT.with(|current| current.borrow_mut().replace(host)));
60 call()
61 }
62
63 fn current() -> Rc<dyn Host> {
64 CURRENT.with(|current| {
65 current
66 .borrow()
67 .clone()
68 .expect("the host function is called only while diffr runs a plugin")
69 })
70 }
71
72 pub(super) fn git(args: &[String]) -> Result<String, String> {
73 current().git(args)
74 }
75}