Files
mandelbrot/src/cli.rs
T
survandClaude Sonnet 5 7c7ca37c4b feat: add a headless mode, driven by clap CLI args
--headless renders the current view straight to a PNG and exits, with
no window/event loop: it builds its own offscreen wgpu device and reuses
the same reference-orbit + ExportRender path as the "Export PNG" button.
--width/--height set the output resolution (default 1920x1080); not yet
supported with --buddhabrot.

Refactors FractalApp::new's state construction and CLI handling into
default_state()/apply_cli() so headless mode can reuse them, and factors
the PNG tile-render/readback/encode loop into a shared
export_to_png_blocking() used by both the windowed export path and
headless.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018GFBP9qrNg6NGJWzzP36xe
2026-09-19 18:03:54 +02:00

99 lines
2.9 KiB
Rust

// Native command-line arguments. Currently mirrors the old `MANDEL_*` debug
// env vars one-for-one; this is the foundation a future headless (no-window,
// render-to-file) mode will build on.
use clap::{Parser, ValueEnum};
use crate::fractal::FractalKind;
#[derive(Parser, Debug, Default)]
#[command(name = "mandelbrot", about = "Deep-zoom fractal explorer", version)]
pub struct Cli {
/// Fractal formula to render.
#[arg(long, value_enum)]
pub kind: Option<KindArg>,
/// Exponent for the Multibrot kind (z -> z^power + c), clamped to [2, 8].
#[arg(long)]
pub power: Option<u32>,
/// Start in Julia mode with this seed constant.
#[arg(long, value_name = "RE,IM")]
pub julia: Option<String>,
/// Restore a view from a share-link fragment (the part after '#').
#[arg(long, value_name = "FRAGMENT")]
pub share: Option<String>,
/// Jump to a view on startup.
#[arg(long, value_name = "RE,IM,HALF_HEIGHT[,ITERATIONS]")]
pub view: Option<String>,
/// Enable distance-estimation shading.
#[arg(long)]
pub de: bool,
/// Switch to the Buddhabrot renderer.
#[arg(long)]
pub buddhabrot: bool,
/// Buddhabrot tonemap palette index.
#[arg(long, value_name = "INDEX")]
pub buddha_palette: Option<u32>,
/// Render a PNG export on startup.
#[arg(long)]
pub export: bool,
/// Output path for --export/--headless (default: fractal-<timestamp>.png).
#[arg(long, value_name = "PATH")]
pub export_path: Option<String>,
/// Run without opening a window: render the current view to a PNG and
/// exit. Combine with --kind/--julia/--share/--view etc. to pick what to
/// render. Not yet supported with --buddhabrot.
#[arg(long)]
pub headless: bool,
/// Output image width in pixels (--headless only).
#[arg(long, value_name = "PX", default_value_t = 1920)]
pub width: u32,
/// Output image height in pixels (--headless only).
#[arg(long, value_name = "PX", default_value_t = 1080)]
pub height: u32,
}
#[derive(Copy, Clone, Debug, ValueEnum)]
pub enum KindArg {
Mandelbrot,
#[value(alias = "ship")]
BurningShip,
#[value(alias = "mandelbar")]
Tricorn,
#[value(alias = "multi")]
Multibrot,
Celtic,
#[value(alias = "perp")]
Perpendicular,
Buffalo,
Phoenix,
Lambda,
}
impl From<KindArg> for FractalKind {
fn from(k: KindArg) -> Self {
match k {
KindArg::Mandelbrot => FractalKind::Mandelbrot,
KindArg::BurningShip => FractalKind::BurningShip,
KindArg::Tricorn => FractalKind::Tricorn,
KindArg::Multibrot => FractalKind::Multibrot,
KindArg::Celtic => FractalKind::Celtic,
KindArg::Perpendicular => FractalKind::Perpendicular,
KindArg::Buffalo => FractalKind::Buffalo,
KindArg::Phoenix => FractalKind::Phoenix,
KindArg::Lambda => FractalKind::Lambda,
}
}
}