wallust/
args.rs

1//! Type declarations for working with clap `derive`, subcommands, flags, value parsers ...
2
3use std::path::PathBuf;
4
5use crate::{
6    backends::Backend,
7    colorspaces::ColorSpace,
8    palettes::Palette,
9    themes::Schemes,
10};
11
12use clap::{Parser, Subcommand};
13use serde::Deserialize;
14
15/// These flags can go before AND after the subcommand, like `wallust -q run image.png` or `wallust run image.png -q`
16#[derive(Debug, Parser, Default)]
17pub struct Globals {
18    /// Won't send these colors sequences
19    #[arg(global = true, short = 'I', long, value_delimiter = ',', conflicts_with = "skip_sequences")]
20    pub ignore_sequence: Option<Vec<Sequences>>,
21
22    /// Don't print anything
23    #[arg(global = true, short, long)]
24    pub quiet: bool,
25
26    /// Skip setting terminal sequences
27    #[arg(global = true, short, long)]
28    #[arg(global = true, short, long, conflicts_with = "update_current", conflicts_with = "ignore_sequence")]
29    pub skip_sequences: bool,
30
31    /// Skip templating process
32    #[arg(global = true, short = 'T', long)]
33    pub skip_templates: bool,
34
35    /// Only update the current terminal
36    #[arg(global = true, short, long, conflicts_with = "skip_sequences")]
37    pub update_current: bool,
38
39    /// Use CONFIG_FILE as the config file
40    #[arg(global = true, short = 'C', long, conflicts_with = "config_dir")]
41    pub config_file: Option<PathBuf>,
42
43    /// Uses CONFIG_DIR as the config directory, which holds both `wallust.toml` and the templates files (if existent)
44    #[arg(global = true, short = 'd', long, conflicts_with = "config_file", conflicts_with = "templates_dir")]
45    pub config_dir: Option<PathBuf>,
46
47    /// Uses TEMPLATE_DIR as the template directory.
48    #[arg(global = true, long, conflicts_with = "config_dir")]
49    pub templates_dir: Option<PathBuf>,
50
51    /// Won't read the config and avoids creating it's config path.
52    #[arg(global = true, short = 'N', long, conflicts_with = "config_file", conflicts_with = "config_dir")]
53    pub no_config: bool,
54}
55
56#[derive(Debug, Parser)]
57pub struct Cli {
58    #[clap(flatten)]
59    pub globals: Globals,
60
61    #[clap(subcommand)]
62    pub subcmds: Subcmds,
63}
64
65
66/// Overall cli type for clap: Possible Subcommands
67#[derive(Debug, Subcommand, Clone)]
68#[command(about, long_about,
69    version = include!(concat!(env!("OUT_DIR"), "/version.rs")),
70    after_help = format!("Remember to read man pages (man wallust.1, man wallust.5, ..)\nAnd the new v3 spec at {}", crate::config::V3),
71    )]
72pub enum Subcmds {
73    /// Generate a palette from an image
74    Run(WallustArgs),
75    /// Apply a certain colorscheme
76    Cs {
77        /// Name of the scheme inside `wallust/colorschemes` directory or the name of a theme.
78        colorscheme: String,
79
80        /// Specify a custom format. Without this option, wallust will sequentially try to decode
81        /// it by trying one by one.
82        #[arg(short, long)]
83        format: Option<Schemes>,
84    },
85
86    /// Apply a custom built in theme
87    #[cfg(feature = "themes")]
88    Theme {
89        /// A custom built in theme to choose from
90        // #[cfg_attr(feature = "buildgen", arg(value_parser = clap::builder::ValueParser::new(col_values)))]
91        // #[cfg_attr(not(feature = "buildgen"), arg(value_parser = include!(concat!(env!("OUT_DIR"), "/args.rs"))))]
92        #[arg(value_parser = include!(concat!(env!("OUT_DIR"), "/args.rs")))]
93        theme: String,
94
95        /// Only preview the selected theme.
96        #[arg(short, long)]
97        preview: bool,
98    },
99    /// Migrate v2 config to v3 (might lose comments,)
100    Migrate,
101    /// Print information about the program and the enviroment it uses
102    Debug,
103
104    /// A drop-in cli replacement for pywal
105    Pywal(PywalArgs),
106
107}
108
109/// No subcommands, global arguments
110#[derive(Parser, Debug, Clone, Default)]
111pub struct WallustArgs {
112    /// Path to the image to use
113    pub file: PathBuf,
114
115    /// Alpha *template variable* value, used only for templating (default is 100)
116    #[arg(short, long, value_parser = 0..=100)]
117    pub alpha: Option<i64>,
118
119    /// Choose which backend to use (overwrites config)
120    #[arg(short, long, value_enum)]
121    pub backend: Option<Backend>,
122
123    /// Choose which colorspace to use (overwrites config)
124    #[arg(short, long, value_enum)]
125    pub colorspace: Option<ColorSpace>,
126
127    /// Choose which fallback generation method to use (overwrites config)
128    #[arg(short, long, value_enum)]
129    pub fallback_generator: Option<crate::colorspaces::FallbackGenerator>,
130
131    /// Ensure a readable contrast by checking colors in reference to the background (overwrites config)
132    #[arg(short = 'k', long)]
133    pub check_contrast: bool,
134
135    /// Don't cache the results
136    #[arg(short, long)]
137    pub no_cache: bool,
138
139    /// Choose which palette to use (overwrites config)
140    #[arg(short, long, value_enum)]
141    pub palette: Option<Palette>,
142
143    /// Add saturation from 1% to 100% (overwrites config)
144    #[arg(long, value_parser = 1..=100)]
145    pub saturation: Option<i64>,
146
147    /// Choose a custom threshold, between 1 and 100 (overwrites config)
148    #[arg(short, long, value_parser = 1..=100)]
149    pub threshold: Option<i64>,
150
151    /// Dynamically changes the threshold to be best fit
152    #[arg(long, conflicts_with = "threshold")]
153    pub dynamic_threshold: bool,
154
155    /// Generates colors even if there is a cache version of it
156    //ref: <https://github.com/dylanaraps/pywal/issues/692>
157    #[arg(short = 'w', long)]
158    pub overwrite_cache: bool,
159}
160
161/// Pywal cli flags arguments. This is to create a drop in replacement, since many apps rely on the
162/// `pywal` command. However, cli flags are ignored, as of now.
163#[derive(Parser, Debug, Clone, Default)]
164#[command(about, long_about)]
165pub struct PywalArgs {
166    /// Set terminal background transparency. *Only works in URxvt*
167    #[arg(short, value_name = "alpha")]
168    pub alpha: Option<String>,
169
170    /// Custom background color to use.
171    #[arg(short, value_name = "background")]
172    pub background: Option<String>,
173
174    /// Which color backend to use
175    #[arg(long, value_name = "[backend]")]
176    pub backend: Option<String>,
177
178    //  --theme [/path/to/file or theme_name], -f [/path/to/file or theme_name]
179    /// Which colorscheme file to use. Use 'wal --theme' to list builtin themes.
180    #[arg(short = 'f', long, value_name = "theme")]
181    pub theme: Option<String>,
182
183    /// When pywal is given a directory as input and this flag is used: Go through the images in order instead of shuffled.
184    #[arg(long)]
185    pub iterative: bool,
186
187    /// Set the color saturation.
188    #[arg(long, value_name = "0.0 - 1.0")]
189    pub saturate: Option<f32>,
190
191    /// Print the current color palette.
192    #[arg(long)]
193    pub preview: bool,
194
195    /// Fix text-artifacts printed in VTE terminals.
196    #[arg(long)]
197    vte: bool,
198
199    /// Delete all cached colorschemes.
200    #[arg(short = 'c')]
201    pub clean_cache: bool,
202
203    /// Which image or directory to use.
204    #[arg(required_unless_present = "theme")]
205    #[arg(short = 'i', value_name = "/path/to/img.jpg")]
206    pub file: Option<PathBuf>,
207
208    /// Generate a light colorscheme.
209    #[arg(short = 'l')]
210    pub light: bool,
211
212    /// Skip setting the wallpaper.
213    #[arg(short = 'n')]
214    pub no_wallpaper: bool,
215
216    /// External script to run after "wal".
217    #[arg(short = 'o', value_name = "script_name")]
218    pub othercmd: Option<String>,
219
220    /// Quiet mode, don't print anything.
221    #[arg(short = 'q')]
222    pub quiet: bool,
223
224    /// 'wal -r' is deprecated: Use (cat ~/.cache/wal/sequences &) instead.
225    #[arg(short = 'r')]
226    pub r: bool,
227
228    /// Restore previous colorscheme.
229    #[arg(short = 'R')]
230    pub restore: bool,
231
232    /// Skip changing colors in terminals.
233    #[arg(short = 's')]
234    pub skip_sequences: bool,
235
236    /// Skip changing colors in tty.
237    #[arg(short = 't')]
238    pub tty: bool,
239
240    /// Print "wal" version.
241    #[arg(short = 'v')]
242    pub version: bool,
243
244    /// Skip reloading gtk/xrdb/i3/sway/polybar
245    #[arg(short = 'e')]
246    pub e: bool,
247}
248
249/// Convert PywalArgs to WallustArgs
250impl From<PywalArgs> for WallustArgs {
251    fn from(p: PywalArgs) -> Self {
252        Self {
253            // All empty so wallust prioritizes the config file
254            alpha: None,
255            backend: None,
256            colorspace: None,
257            check_contrast: false,
258            dynamic_threshold: true,
259            fallback_generator: None,
260            no_cache: false,
261            overwrite_cache: false,
262            palette: None,
263            saturation: None,
264            threshold: None,
265            file: p.file.expect("ALWAYS SOME, CHECKED ON MAIN"),
266        }
267    }
268}
269
270#[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize, clap::ValueEnum)]
271#[serde(rename_all = "lowercase")]
272pub enum Sequences {
273    Background,
274    Foreground,
275    Cursor,
276    Color0,
277    Color1,
278    Color2,
279    Color3,
280    Color4,
281    Color5,
282    Color6,
283    Color7,
284    Color8,
285    Color9,
286    Color10,
287    Color11,
288    Color12,
289    Color13,
290    Color14,
291    Color15,
292}