euv_cli/build/struct.rs
1use super::*;
2
3/// euv CLI for real-time WASM compilation and hot-reload development server.
4///
5/// Defines the command-line interface with three sub-commands
6/// (`run` / `build` / `fmt`). All arguments after `--` are transparently
7/// forwarded to `wasm-pack build` without interpretation.
8#[derive(Clone, Data, Debug, New, Parser)]
9#[command(name = "euv")]
10#[command(about = "euv development server with live WASM compilation")]
11pub struct Cli {
12 /// The mode to run in: run (build + server), build (build only), or fmt (format)
13 #[command(subcommand)]
14 ///
15 /// Public: `cli/src/main.rs` is the `--bin euv` crate root, a
16 /// different crate from the `euv_cli` library, so its
17 /// `cli.get_command()` call cannot see a `pub(crate)` accessor. The
18 /// field is public to match that getter rather than the getter
19 /// narrowed to `pub(crate)`, which would fail with E0624 at the bin
20 /// call site. `get_mut` / `set` stay crate-internal — clap's derive
21 /// is the only writer and nothing mutates the mode in place.
22 #[get_mut(pub(crate))]
23 #[set(pub(crate))]
24 pub command: Mode,
25}
26
27/// euv-specific arguments combined with wasm-pack passthrough.
28///
29/// Only `--crate-path`, `--port`, `--www-dir`, `--index-html`, `--no-gitignore`, and `--dev`/`--release`/`--profiling`
30/// belong to euv; everything in `wasm_pack_args` is forwarded to `wasm-pack build` as-is.
31#[derive(Clone, Data, Debug, Parser)]
32pub struct ModeArgs {
33 /// Path to the Rust crate containing the WASM application
34 #[arg(short, long, default_value = ".")]
35 #[get(pub(crate))]
36 #[get_mut(pub(crate))]
37 #[set(pub(crate))]
38 pub(crate) crate_path: PathBuf,
39 /// Port for the development server
40 #[arg(short, long, default_value_t = 80)]
41 #[get(pub(crate), type(copy))]
42 #[get_mut(pub(crate))]
43 #[set(pub(crate))]
44 pub(crate) port: u16,
45 /// Directory name for static assets and generated HTML (relative to crate-path)
46 #[arg(long, default_value = "www")]
47 #[get(pub(crate))]
48 #[get_mut(pub(crate))]
49 #[set(pub(crate))]
50 pub(crate) www_dir: String,
51 /// Path to a custom index.html template file.
52 /// When specified, uses this file instead of the built-in template.
53 /// The placeholders `__IMPORT_PATH__` and `__RELOAD_ROUTE__` will be replaced.
54 #[arg(long)]
55 #[get(pub(crate))]
56 #[get_mut(pub(crate))]
57 #[set(pub(crate))]
58 pub(crate) index_html: Option<PathBuf>,
59 /// Create a development build. Enable debug info, and disable optimizations
60 #[arg(long)]
61 #[get(pub(crate), type(copy))]
62 #[get_mut(pub(crate))]
63 #[set(pub(crate))]
64 pub(crate) dev: bool,
65 /// Create a release build. Enable optimizations and disable debug info
66 #[arg(long)]
67 #[get(pub(crate), type(copy))]
68 #[get_mut(pub(crate))]
69 #[set(pub(crate))]
70 pub(crate) release: bool,
71 /// Create a profiling build. Enable optimizations and debug info
72 #[arg(long)]
73 #[get(pub(crate), type(copy))]
74 #[get_mut(pub(crate))]
75 #[set(pub(crate))]
76 pub(crate) profiling: bool,
77 /// Remove the .gitignore file from the output directory after building
78 #[arg(long)]
79 #[get(pub(crate), type(copy))]
80 #[get_mut(pub(crate))]
81 #[set(pub(crate))]
82 pub(crate) no_gitignore: bool,
83 /// Arguments transparently forwarded to `wasm-pack build`
84 #[arg(trailing_var_arg = true, allow_hyphen_values = true)]
85 #[get(pub(crate))]
86 #[get_mut(pub(crate))]
87 #[set(pub(crate))]
88 pub(crate) wasm_pack_args: Vec<String>,
89}
90
91/// Arguments for the `fmt` subcommand.
92///
93/// Formats euv macro invocations (`html!`, `class!`, `vars!`, `watch!`)
94/// in Rust source files.
95#[derive(Clone, Debug, Getter, New, Parser)]
96pub struct FmtArgs {
97 /// Path to the directory or file to format
98 #[arg(short, long, default_value = ".")]
99 ///
100 /// Narrowed to `pub(crate)`: the only getter call sites are in
101 /// `cli/src/mode/fn.rs`, which is inside this crate. The integration
102 /// test constructs a `FmtArgs` through `FmtArgs::new` /
103 /// `FmtArgs::parse_from` but never reads the field, so no public
104 /// accessor is required. `Getter` does not generate mutators — no
105 /// caller anywhere mutates the path after parsing.
106 #[get(pub(crate))]
107 pub(crate) path: PathBuf,
108 /// Check if formatting is needed without modifying files
109 #[arg(long, default_value_t = false)]
110 ///
111 /// Narrowed for the same reason as [`FmtArgs::path`]: the flag is read
112 /// only by `cli/src/mode/fn.rs`, and clap's derive is what writes it,
113 /// so `Getter` is the right derive — it generates no mutators.
114 #[get(pub(crate), type(copy))]
115 pub(crate) check: bool,
116}
117
118/// Configuration for server URL display.
119///
120/// Groups all parameters needed by `print_server_urls` into a single struct.
121#[derive(Clone, Data, Debug, New)]
122pub(crate) struct ServerUrlConfig {
123 /// The port number the server is listening on.
124 #[get(pub(crate), type(copy))]
125 #[get_mut(pub(crate))]
126 #[set(pub(crate))]
127 pub(crate) port: u16,
128 /// The serving route prefix (e.g. "www" or "wwws").
129 #[get(pub(crate))]
130 #[get_mut(pub(crate))]
131 #[set(pub(crate))]
132 pub(crate) route_prefix: String,
133 /// The index HTML file name (e.g. "index.html").
134 #[get(pub(crate))]
135 #[get_mut(pub(crate))]
136 #[set(pub(crate))]
137 pub(crate) index_html_file_name: String,
138}
139
140/// One static `import` clause of the wasm-bindgen bridge, parsed into the
141/// bindings a self-contained bootstrap can reproduce.
142///
143/// A single clause carries at most one of the three binding forms: a
144/// namespace alias (`* as alias`), a list of named bindings (`{ a, b }`),
145/// or a default binding. The borrowed lifetimes tie every binding and the
146/// module specifier to the bridge source line they were sliced from.
147#[derive(Debug)]
148pub struct ImportClause<'a> {
149 /// The module specifier, with its quotes and trailing semicolon removed.
150 pub spec: &'a str,
151 /// The local binding of a `* as alias` namespace import.
152 pub namespace: Option<&'a str>,
153 /// The local binding of a default import.
154 pub default_binding: Option<&'a str>,
155 /// The bindings of a `{ a, b }` named import, in source order.
156 pub named: Vec<&'a str>,
157}
158
159/// A namespace import clause found in the bridge: `import * as alias from
160/// "spec"`.
161///
162/// Collected while scanning the bridge's imports so the inlined bootstrap
163/// can rebuild the alias as a plain object once the module graph is gone.
164/// The owned form exists so a namespace binding survives the async read of
165/// the snippet module it points at.
166#[derive(Debug)]
167pub(crate) struct NamespaceImport {
168 /// The local binding the clause introduces.
169 pub(crate) alias: String,
170 /// The module specifier, verbatim with its quotes.
171 pub(crate) spec: String,
172}