app
Adom Chipsmith
Public Made by Adomby adom
STEP-native chip validator — 5-source cross-validation, OCCT-generated copyright-free 3D models with embedded signal annotations, datasheet-to-STEP pipeline.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
use crate::cli::{err, hint, DEFAULT_PORT};
use anyhow::Result;
use clap::Parser;
use std::time::{Duration, Instant};
#[derive(Parser)]
pub struct Args {
/// JS snippet to run inside the adom-step webview. Wrap `await` freely;
/// the UI invokes via AsyncFunction so top-level await works.
pub code: String,
/// How long to wait for the UI to return a result.
#[arg(long, default_value_t = 5)]
pub timeout_secs: u64,
#[arg(long)]
pub quiet: bool,
#[arg(long, default_value_t = DEFAULT_PORT)]
pub port: u16,
}
pub fn run(args: Args) -> Result<()> {
eval_snippet(&args.code, args.timeout_secs, args.port, args.quiet).map(|v| {
println!("{}", serde_json::to_string_pretty(&v).unwrap_or_default());
})
}
/// Reusable helper for other CLI subcommands that need to drive the UI via JS.
pub fn eval_snippet(code: &str, timeout_secs: u64, port: u16, quiet: bool) -> Result<serde_json::Value> {
let base = format!("http://127.0.0.1:{}", port);
let queue: serde_json::Value = match ureq::post(&format!("{base}/eval"))
.timeout(Duration::from_secs(2))
.send_json(serde_json::json!({"code": code}))
{
Ok(r) => r.into_json()?,
Err(e) => {
err(format!("could not reach adom-step: {e}"));
hint("start it first with `adom-step view <file.step>`");
return Err(anyhow::anyhow!("unreachable"));
}
};
let id = queue
.get("id")
.and_then(|v| v.as_str())
.ok_or_else(|| anyhow::anyhow!("server returned no id: {queue}"))?
.to_string();
if !quiet {
eprintln!("queued {id}");
}
let deadline = Instant::now() + Duration::from_secs(timeout_secs);
loop {
if Instant::now() >= deadline {
err(format!("timeout waiting for result of {id}"));
hint("is the webview open and loaded?");
return Err(anyhow::anyhow!("timeout"));
}
let r: serde_json::Value = ureq::get(&format!("{base}/eval/{id}"))
.timeout(Duration::from_secs(2))
.call()?
.into_json()?;
if r.get("done").and_then(|v| v.as_bool()).unwrap_or(false) {
return Ok(r.get("result").cloned().unwrap_or(serde_json::Value::Null));
}
std::thread::sleep(Duration::from_millis(150));
}
}