1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
//! `inkhaven bund <code>` — evaluate a Bund expression and print the
//! top of the workbench.
//!
//! Phase-0 smoke entry point. If the working directory (or
//! `--project`) is an initialised inkhaven project, the store is
//! opened — which auto-arms the scripting layer via
//! `Store::open` → `scripting::configure` — and `ink.*` words
//! become available. Otherwise the script runs against the bare
//! Adam VM (pure arithmetic / strings / control flow).
//!
//! The store-open path triggers fastembed model load on first use,
//! which is slow (~seconds). We avoid that for arithmetic-only
//! scripts by skipping the open when the path isn't an inkhaven
//! project.
use std::path::Path;
use anyhow::Result;
use crate::config::Config;
use crate::project::ProjectLayout;
use crate::store::Store;
pub fn run(code: &str, project: &Path) -> Result<()> {
maybe_open_project(project);
let out = crate::scripting::eval(code)?;
// print/println captured during the eval — emit before the
// result so the user sees them in script order.
if !out.stdout.is_empty() {
print!("{}", out.stdout);
// Ensure a trailing newline so the result on the next
// line isn't smashed against the buffer's last character.
if !out.stdout.ends_with('\n') {
println!();
}
}
match out.top {
Some(value) => println!("{}", crate::scripting::format_value(&value)),
None if out.stdout.is_empty() => println!("(no result)"),
None => {} // stdout was already shown; nothing to add
}
Ok(())
}
/// Open the project at `project` when it's a real inkhaven
/// directory. `Store::open` itself arms the scripting layer
/// (policy + active store) — we don't need to wire anything
/// else here.
fn maybe_open_project(project: &Path) {
let layout = ProjectLayout::new(project);
if layout.require_initialized().is_err() {
return;
}
let cfg = match Config::load_layered(&layout.config_path()) {
Ok(c) => c,
Err(_) => return,
};
let _ = Store::open(layout, &cfg);
}