azalea_core/
cli.rs

1use clap::{Parser, arg, command};
2
3use crate::log;
4
5/// Command line arguments
6#[derive(clap::Parser, serde::Serialize)]
7#[command(version, about, long_about = None)]
8pub struct Arguments {
9    #[command(subcommand)]
10    pub command: Command,
11
12    /// Wait for daemon to start
13    #[clap(short, long)]
14    pub wait_for_daemon: bool,
15
16    /// Arguments passed to GTK.
17    #[arg(allow_hyphen_values = true, trailing_var_arg = true)]
18    pub gtk_options: Vec<String>,
19}
20
21impl Arguments {
22    pub fn parse(after_help: impl clap::builder::IntoResettable<clap::builder::StyledStr>) -> Self {
23        let mut matches = <Self as clap::CommandFactory>::command()
24            .after_help(after_help)
25            .get_matches();
26        let res = <Self as clap::FromArgMatches>::from_arg_matches_mut(&mut matches);
27        match res {
28            Ok(s) => s,
29            Err(e) => {
30                log::error!("Failed to parse cli arguments {e}");
31            }
32        }
33    }
34}
35
36/// Main command line commands
37#[derive(Parser, serde::Serialize, serde::Deserialize, Debug)]
38pub enum Command {
39    #[command(subcommand)]
40    Daemon(daemon::Command),
41
42    #[command(subcommand)]
43    Window(window::Command),
44
45    #[command(subcommand)]
46    Layer(layer_shell::Command),
47
48    #[command(subcommand)]
49    Config(config::Command),
50
51    Monitors,
52
53    #[command(subcommand)]
54    Style(style::Command),
55    // TODO: Extra subcommand given by the user?
56}
57
58pub mod daemon {
59    #[derive(clap::Parser, serde::Serialize, serde::Deserialize, Debug)]
60    pub enum Command {
61        Start {
62            #[clap(long)]
63            config: Option<String>,
64        },
65        Stop,
66    }
67}
68
69pub mod window {
70    use crate::config;
71
72    #[derive(clap::Parser, serde::Serialize, serde::Deserialize, Debug)]
73    pub enum Command {
74        Create(CreateArgs),
75        Toggle(ToggleArgs),
76        Uuid,
77    }
78
79    #[derive(clap::Parser, serde::Serialize, serde::Deserialize, Debug)]
80    pub struct ToggleArgs {
81        pub uuid: String,
82    }
83
84    #[derive(clap::Parser, serde::Serialize, serde::Deserialize, Debug)]
85    pub struct CreateArgs {
86        pub id: config::window::Id,
87    }
88}
89
90pub mod layer_shell {
91    use gtk4_layer_shell::LayerShell;
92
93    use crate::config::layer_shell::{Anchor, Layer};
94
95    #[derive(clap::Parser, serde::Serialize, serde::Deserialize, Debug)]
96    pub enum Command {
97        Toggle(Arguments),
98    }
99
100    #[derive(clap::Parser, serde::Serialize, serde::Deserialize, Debug)]
101    pub struct Arguments {
102        pub namespace: crate::config::layer_shell::Namespace,
103
104        #[clap(long)]
105        pub layer: Option<Layer>,
106
107        #[clap(long)]
108        pub anchors: Vec<Anchor>,
109    }
110
111    impl Arguments {
112        pub fn cmp(&self, window: &gtk::Window) -> bool {
113            let Some(namespace) = window.namespace() else {
114                return false;
115            };
116            if self.namespace != namespace {
117                return false;
118            }
119
120            if let Some(layer) = &self.layer {
121                let win_layer = window.layer();
122                if Into::<gtk4_layer_shell::Layer>::into(layer) != win_layer {
123                    return false;
124                }
125            }
126
127            for anchor in &self.anchors {
128                if !window.is_anchor(anchor.into()) {
129                    return false;
130                };
131            }
132
133            return true;
134        }
135    }
136}
137
138pub mod config {
139    #[derive(clap::Parser, serde::Serialize, serde::Deserialize, Debug)]
140    pub enum Command {
141        View {
142            #[clap(long)]
143            json: bool,
144        },
145    }
146}
147
148pub mod style {
149    #[derive(clap::Parser, serde::Serialize, serde::Deserialize, Debug)]
150    pub enum Command {
151        /// Reload style from css file
152        Reload {
153            /// Path to css file
154            #[clap(long)]
155            file: Option<std::path::PathBuf>,
156        },
157        /// Loads default css style
158        Default,
159    }
160}
161
162#[derive(serde::Serialize, serde::Deserialize)]
163pub enum Response {
164    Success(String),
165    Error(String),
166}