Skip to main content

xtask_lib/tasks/
run_emulator.rs

1//! `cargo xtask run-emulator` — run the Cadmus emulator.
2//!
3//! Ensures the embedded documentation EPUB is ready, then launches
4//! `cargo run -p emulator`.  Any extra arguments are forwarded to the cargo invocation.
5//! Native dependencies (MuPDF, libwebp) are built automatically by `build.rs`.
6
7use std::path::Path;
8
9use anyhow::Result;
10use clap::Args;
11
12use super::docs::{self, DocsArgs};
13use super::util::{cmd, workspace};
14
15/// Arguments for `cargo xtask run-emulator`.
16#[derive(Debug, Args)]
17pub struct RunEmulatorArgs {
18    /// Cargo feature flags forwarded to `cargo run -p emulator`.
19    #[arg(long)]
20    pub features: Option<String>,
21
22    /// Extra arguments forwarded to `cargo run -p emulator`.
23    #[arg(trailing_var_arg = true, allow_hyphen_values = true)]
24    pub extra: Vec<String>,
25}
26
27/// Returns `true` when the documentation EPUB embedded by `cadmus-core` exists.
28fn mdbook_epub_built(root: &Path) -> bool {
29    root.join("docs/book/epub/Cadmus Documentation.epub")
30        .exists()
31}
32
33/// Ensures documentation is built then launches the emulator.
34pub fn run(args: RunEmulatorArgs) -> Result<()> {
35    let root = workspace::root()?;
36
37    if !mdbook_epub_built(&root) {
38        println!("Documentation EPUB not found — building mdBook…");
39        docs::run(DocsArgs {
40            base_url: "http://localhost".to_string(),
41            mdbook_only: true,
42        })?;
43    }
44
45    let mut cargo_args = vec!["run", "-p", "emulator"];
46
47    if let Some(features) = args.features.as_deref() {
48        cargo_args.push("--features");
49        cargo_args.push(features);
50    }
51
52    let extra_refs: Vec<&str> = args.extra.iter().map(String::as_str).collect();
53    cargo_args.extend_from_slice(&extra_refs);
54
55    cmd::run("cargo", &cargo_args, &root, &[])
56}