spyglass_plugin/
shims.rs

1use serde::{de::DeserializeOwned, Serialize};
2use std::io;
3
4use crate::{ListDirEntry, PluginCommandRequest, PluginSubscription};
5
6pub fn delete_doc(url: &str) {
7    if object_to_stdout(&PluginCommandRequest::DeleteDoc {
8        url: url.to_string(),
9    })
10    .is_ok()
11    {
12        unsafe {
13            plugin_cmd();
14        }
15    }
16}
17
18pub fn subscribe(event: PluginSubscription) {
19    if object_to_stdout(&PluginCommandRequest::Subscribe(event)).is_ok() {
20        unsafe {
21            plugin_cmd();
22        }
23    }
24}
25
26/// Add an item to the Spyglass crawl queue
27pub fn enqueue_all(urls: &[String]) {
28    if object_to_stdout(&PluginCommandRequest::Enqueue { urls: urls.into() }).is_ok() {
29        unsafe {
30            plugin_cmd();
31        }
32    }
33}
34
35/// List dir
36pub fn list_dir(path: &str) -> Result<Vec<ListDirEntry>, ron::error::SpannedError> {
37    if object_to_stdout(&PluginCommandRequest::ListDir {
38        path: path.to_string(),
39    })
40    .is_ok()
41    {
42        unsafe {
43            plugin_cmd();
44        }
45        return object_from_stdin::<Vec<ListDirEntry>>();
46    }
47
48    Ok(Vec::new())
49}
50
51/// Utility function to log to spyglass logs
52pub fn log(msg: String) {
53    println!("{}", msg);
54    unsafe {
55        plugin_log();
56    }
57}
58
59/// Hacky workaround until rusqlite can compile to wasm easily.
60/// Path is expected to be rooted in the plugins data directory.
61pub fn sqlite3_query(path: &str, query: &str) -> Result<Vec<String>, ron::error::SpannedError> {
62    if object_to_stdout(&PluginCommandRequest::SqliteQuery {
63        path: path.to_string(),
64        query: query.to_string(),
65    })
66    .is_ok()
67    {
68        unsafe { plugin_cmd() };
69        return object_from_stdin::<Vec<String>>();
70    }
71
72    Ok(Vec::new())
73}
74
75/// Adds / updates a file in the plugin VFS from the host.
76pub fn sync_file(dst: String, src: String) {
77    if object_to_stdout(&PluginCommandRequest::SyncFile { dst, src }).is_ok() {
78        unsafe {
79            plugin_cmd();
80        }
81    }
82}
83
84#[link(wasm_import_module = "spyglass")]
85extern "C" {
86    fn plugin_cmd();
87    fn plugin_log();
88}
89
90#[doc(hidden)]
91pub fn object_from_stdin<T: DeserializeOwned>() -> Result<T, ron::error::SpannedError> {
92    let mut buf = String::new();
93    io::stdin().read_line(&mut buf).unwrap();
94    ron::from_str(&buf)
95}
96
97#[doc(hidden)]
98pub fn object_to_stdout(obj: &impl Serialize) -> Result<(), ron::Error> {
99    println!("{}", ron::ser::to_string(obj)?);
100    Ok(())
101}