1use crate::doc::Doc;
9use crate::{Cell, Executor};
10use quarb::QueryResult;
11
12pub struct LocalExecutor {
13 doc: Doc,
14 now: (i64, u32),
16 allow_shell: bool,
17 #[cfg(feature = "native")]
21 respec: Option<(Vec<std::path::PathBuf>, crate::Options)>,
22}
23
24impl LocalExecutor {
25 pub fn new(doc: Doc, now: (i64, u32), allow_shell: bool) -> Self {
27 Self {
28 doc,
29 now,
30 allow_shell,
31 #[cfg(feature = "native")]
32 respec: None,
33 }
34 }
35
36 #[cfg(feature = "native")]
39 pub fn with_respec(
40 doc: Doc,
41 now: (i64, u32),
42 allow_shell: bool,
43 paths: Vec<std::path::PathBuf>,
44 opts: crate::Options,
45 ) -> Self {
46 Self {
47 doc,
48 now,
49 allow_shell,
50 respec: Some((paths, opts)),
51 }
52 }
53}
54
55fn run_doc(doc: &Doc, query: &str, now: (i64, u32), allow_shell: bool) -> anyhow::Result<Vec<Cell>> {
57 let result = doc
58 .run(query, now, allow_shell)
59 .map_err(|e| anyhow::anyhow!("{e}"))?;
60 Ok(match result {
61 QueryResult::Nodes(nodes) => nodes.into_iter().map(|n| Cell::Node(doc.render(n))).collect(),
62 QueryResult::Values(values) => values.into_iter().map(Cell::Value).collect(),
63 })
64}
65
66impl Executor for LocalExecutor {
67 fn run(&self, query: &str) -> anyhow::Result<Vec<Cell>> {
68 run_doc(&self.doc, query, self.now, self.allow_shell)
69 }
70
71 fn run_fresh(&self, query: &str) -> anyhow::Result<Vec<Cell>> {
72 #[cfg(feature = "native")]
73 if let Some((paths, opts)) = &self.respec {
74 let fresh = match paths.as_slice() {
75 [one] => Doc::open(one, opts)?,
76 many => Doc::mount(many, opts)?,
77 };
78 return run_doc(&fresh, query, self.now, self.allow_shell);
79 }
80 self.run(query)
81 }
82}