forked from linux-surface/surface-control
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathprofile.rs
More file actions
141 lines (108 loc) · 4.3 KB
/
profile.rs
File metadata and controls
141 lines (108 loc) · 4.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
use crate::cli::Command as DynCommand;
use crate::sys;
use anyhow::{Context, Result};
pub struct Command;
impl DynCommand for Command {
fn name(&self) -> &'static str {
"profile"
}
fn build(&self) -> clap::Command {
use clap::Arg;
clap::Command::new(self.name())
.about("Control or query the current platform profile")
.subcommand_required(true)
.arg_required_else_help(true)
.infer_subcommands(true)
.subcommand(clap::Command::new("set")
.about("Set the current platform profile")
.arg(Arg::new("profile")
.required(true)
.index(1)))
.subcommand(clap::Command::new("get")
.about("Get the current platform profile"))
.subcommand(clap::Command::new("list")
.about("List all available platform profiles"))
.subcommand(clap::Command::new("cycle")
.about("Cycle to the next platform profile"))
}
fn execute(&self, m: &clap::ArgMatches) -> Result<()> {
match m.subcommand() {
Some(("set", m)) => self.profile_set(m),
Some(("get", m)) => self.profile_get(m),
Some(("list", m)) => self.profile_list(m),
Some(("cycle", m)) => self.profile_cycle(m),
_ => unreachable!(),
}
}
}
impl Command {
fn profile_set(&self, m: &clap::ArgMatches) -> Result<()> {
let profile: &String = m.get_one("profile").unwrap();
let dev = sys::profile::Device::open()
.context("Failed to open platform profile device")?;
let supported = dev.get_supported()
.context("Failed to get supported platform profiles")?;
if !supported.iter().any(|p| p == profile) {
anyhow::bail!("Platform profile '{profile}' is not supported");
}
let current_profile = dev.get()
.context("Failed to get current platform profile")?;
if profile != ¤t_profile {
dev.set(profile)
.context("Failed to set platform profile")?;
if !m.get_flag("quiet") {
println!("Platform profile set to '{profile}'");
}
} else if !m.get_flag("quiet") {
println!("Platform profile already set to '{profile}', not changing");
}
Ok(())
}
fn profile_get(&self, _m: &clap::ArgMatches) -> Result<()> {
let dev = sys::profile::Device::open()
.context("Failed to open platform profile device")?;
let profile = dev.get()
.context("Failed to get current platform profile")?;
println!("{profile}");
Ok(())
}
fn profile_list(&self, m: &clap::ArgMatches) -> Result<()> {
let dev = sys::profile::Device::open()
.context("Failed to open platform profile device")?;
let supported = dev.get_supported()
.context("Failed to get supported platform profiles")?;
if !m.get_flag("quiet") {
for profile in supported {
println!("{profile}");
}
} else {
let text = serde_json::to_string(&supported)
.context("Failed to serialize data")?;
println!("{text}");
}
Ok(())
}
fn profile_cycle(&self, m: &clap::ArgMatches) -> Result<()> {
let dev = sys::profile::Device::open()
.context("Failed to open platform profile device")?;
let supported = dev.get_supported()
.context("Failed to get supported platform profiles")?;
if supported.is_empty() {
anyhow::bail!("No platform profiles available");
}
let current_profile = dev.get()
.context("Failed to get current platform profile")?;
// Find the next profile in the list, wrapping around to the start
let next_profile = supported.iter()
.cycle()
.skip_while(|&p| p != ¤t_profile)
.nth(1)
.unwrap_or(&supported[0]);
dev.set(next_profile)
.context("Failed to set platform profile")?;
if !m.get_flag("quiet") {
println!("Platform profile cycled from '{current_profile}' to '{next_profile}'");
}
Ok(())
}
}