Krolyxon
Commit 92928dd

Branches

Tags

Refs →

remagesrccli.rs

100 lines · 2.6 KB · Rust

1//! Command-line interface.
2
3use std::path::PathBuf;
4
5use clap::Parser;
6
7use crate::state::queue::SortKey;
8use crate::state::view::FitMode;
9
10#[derive(Parser, Debug)]
11#[command(name = "remage", version, about = "Keyboard-centric image viewer")]
12pub struct Cli {
13 /// Files or directories to open [default: .]
14 pub paths: Vec<PathBuf>,
15
16 /// Descend into directories
17 #[arg(short, long)]
18 pub recursive: bool,
19
20 /// Start at the Nth image (1-based)
21 #[arg(short = 'n', long, value_name = "N")]
22 pub start: Option<usize>,
23
24 /// Start in fullscreen
25 #[arg(short, long)]
26 pub fullscreen: bool,
27
28 /// Hide the status bar
29 #[arg(short = 'b', long)]
30 pub no_bar: bool,
31
32 /// How images fit the window
33 #[arg(short = 's', long, value_enum, value_name = "MODE")]
34 pub fit: Option<FitMode>,
35
36 /// Fixed zoom level in percent (overrides --fit)
37 #[arg(short = 'z', long, value_name = "PCT")]
38 pub zoom: Option<f32>,
39
40 /// Initial window size in logical pixels
41 #[arg(short = 'g', long, value_name = "WxH", value_parser = parse_geometry)]
42 pub geometry: Option<(u32, u32)>,
43
44 /// Wayland app_id / X11 class [default: remage]
45 #[arg(long, value_name = "NAME")]
46 pub class: Option<String>,
47
48 /// Sort order for directory contents [default: natural]
49 #[arg(long, value_enum, value_name = "KEY")]
50 pub sort: Option<SortKey>,
51
52 /// Reverse the sort order
53 #[arg(long)]
54 pub reverse: bool,
55
56 /// Open only the named file, not the rest of its directory
57 #[arg(long)]
58 pub no_siblings: bool,
59
60 /// Config file [default: $XDG_CONFIG_HOME/remage/config.toml]
61 #[arg(short = 'c', long, value_name = "PATH")]
62 pub config: Option<PathBuf>,
63
64 /// Print the full commented default config and exit
65 #[arg(long)]
66 pub dump_config: bool,
67
68 /// Validate the config and exit non-zero on errors
69 #[arg(long)]
70 pub check_config: bool,
71}
72
73fn parse_geometry(s: &str) -> Result<(u32, u32), String> {
74 let (w, h) = s
75 .split_once(['x', 'X'])
76 .ok_or("expected WxH, e.g. 1280x800")?;
77 let parse = |v: &str| v.trim().parse::<u32>().ok().filter(|n| *n > 0);
78 match (parse(w), parse(h)) {
79 (Some(w), Some(h)) => Ok((w, h)),
80 _ => Err("expected positive WxH, e.g. 1280x800".into()),
81 }
82}
83
84#[cfg(test)]
85mod tests {
86 use super::*;
87 use clap::CommandFactory;
88
89 #[test]
90 fn cli_is_consistent() {
91 Cli::command().debug_assert();
92 }
93
94 #[test]
95 fn geometry() {
96 assert_eq!(parse_geometry("800x600"), Ok((800, 600)));
97 assert!(parse_geometry("800").is_err());
98 assert!(parse_geometry("0x600").is_err());
99 }
100}