mirror of
https://codeberg.org/Codeberg/pages-server.git
synced 2025-01-19 00:57:53 +00:00
initial commit
This commit is contained in:
commit
363c6a18c4
11 changed files with 589 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
target/
|
4
90-backlight.rules
Normal file
4
90-backlight.rules
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
ACTION=="add", SUBSYSTEM=="backlight", RUN+="/bin/chgrp video /sys/class/backlight/%k/brightness"
|
||||||
|
ACTION=="add", SUBSYSTEM=="backlight", RUN+="/bin/chmod g+w /sys/class/backlight/%k/brightness"
|
||||||
|
ACTION=="add", SUBSYSTEM=="leds", RUN+="/bin/chgrp video /sys/class/leds/%k/brightness"
|
||||||
|
ACTION=="add", SUBSYSTEM=="leds", RUN+="/bin/chmod g+w /sys/class/leds/%k/brightness"
|
120
Cargo.lock
generated
Normal file
120
Cargo.lock
generated
Normal file
|
@ -0,0 +1,120 @@
|
||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
[[package]]
|
||||||
|
name = "ansi_term"
|
||||||
|
version = "0.11.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
|
||||||
|
dependencies = [
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "atty"
|
||||||
|
version = "0.2.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
||||||
|
dependencies = [
|
||||||
|
"hermit-abi",
|
||||||
|
"libc",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "1.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap"
|
||||||
|
version = "2.33.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9"
|
||||||
|
dependencies = [
|
||||||
|
"ansi_term",
|
||||||
|
"atty",
|
||||||
|
"bitflags",
|
||||||
|
"strsim",
|
||||||
|
"textwrap",
|
||||||
|
"unicode-width",
|
||||||
|
"vec_map",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "exitcode"
|
||||||
|
version = "1.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "de853764b47027c2e862a995c34978ffa63c1501f2e15f987ba11bd4f9bba193"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hermit-abi"
|
||||||
|
version = "0.1.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8a0d737e0f947a1864e93d33fdef4af8445a00d1ed8dc0c8ddb73139ea6abf15"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lamp"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"clap",
|
||||||
|
"exitcode",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libc"
|
||||||
|
version = "0.2.69"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "99e85c08494b21a9054e7fe1374a732aeadaff3980b6990b94bfd3a70f690005"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "strsim"
|
||||||
|
version = "0.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "textwrap"
|
||||||
|
version = "0.11.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-width",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-width"
|
||||||
|
version = "0.1.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "caaa9d531767d1ff2150b9332433f32a24622147e5ebb1f26409d5da67afd479"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "vec_map"
|
||||||
|
version = "0.8.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi"
|
||||||
|
version = "0.3.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6"
|
||||||
|
dependencies = [
|
||||||
|
"winapi-i686-pc-windows-gnu",
|
||||||
|
"winapi-x86_64-pc-windows-gnu",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-i686-pc-windows-gnu"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-x86_64-pc-windows-gnu"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
16
Cargo.toml
Normal file
16
Cargo.toml
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
[package]
|
||||||
|
name = "lamp"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["crapStone <wewr.mc@gmail.com>"]
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
build = "build.rs"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[build-dependencies]
|
||||||
|
clap = "2.33"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
clap = "2.33"
|
||||||
|
exitcode = "1.1.2"
|
4
README.md
Normal file
4
README.md
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
# Lamp
|
||||||
|
|
||||||
|
Lamp is a backlight control program written in Rust and inspired by
|
||||||
|
[acpibacklight](https://gitlab.com/wavexx/acpilight).
|
14
build.rs
Normal file
14
build.rs
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
use clap::Shell;
|
||||||
|
|
||||||
|
include!("src/cli.rs");
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let outdir = "completions"; // match env::var_os("OUT_DIR") {
|
||||||
|
// None => return,
|
||||||
|
// Some(outdir) => outdir,
|
||||||
|
// };
|
||||||
|
let mut app = build_cli();
|
||||||
|
app.gen_completions("lamp", Shell::Fish, outdir);
|
||||||
|
// app.gen_completions("lamp", Shell::Zsh, outdir); // TODO search for bug
|
||||||
|
app.gen_completions("lamp", Shell::Bash, outdir);
|
||||||
|
}
|
73
completions/lamp.bash
Normal file
73
completions/lamp.bash
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
_lamp() {
|
||||||
|
local i cur prev opts cmds
|
||||||
|
COMPREPLY=()
|
||||||
|
cur="${COMP_WORDS[COMP_CWORD]}"
|
||||||
|
prev="${COMP_WORDS[COMP_CWORD-1]}"
|
||||||
|
cmd=""
|
||||||
|
opts=""
|
||||||
|
|
||||||
|
for i in ${COMP_WORDS[@]}
|
||||||
|
do
|
||||||
|
case "${i}" in
|
||||||
|
lamp)
|
||||||
|
cmd="lamp"
|
||||||
|
;;
|
||||||
|
|
||||||
|
*)
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
case "${cmd}" in
|
||||||
|
lamp)
|
||||||
|
opts=" -g -z -f -l -h -V -s -i -d -t --get --zero --full --list --help --version --set --increase --decrease --type "
|
||||||
|
if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
|
||||||
|
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
case "${prev}" in
|
||||||
|
|
||||||
|
--set)
|
||||||
|
COMPREPLY=($(compgen -f "${cur}"))
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
-s)
|
||||||
|
COMPREPLY=($(compgen -f "${cur}"))
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
--increase)
|
||||||
|
COMPREPLY=($(compgen -f "${cur}"))
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
-i)
|
||||||
|
COMPREPLY=($(compgen -f "${cur}"))
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
--decrease)
|
||||||
|
COMPREPLY=($(compgen -f "${cur}"))
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
-d)
|
||||||
|
COMPREPLY=($(compgen -f "${cur}"))
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
--type)
|
||||||
|
COMPREPLY=($(compgen -W "raw lin log" -- "${cur}"))
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
-t)
|
||||||
|
COMPREPLY=($(compgen -W "raw lin log" -- "${cur}"))
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
COMPREPLY=()
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
complete -F _lamp -o bashdefault -o default lamp
|
10
completions/lamp.fish
Normal file
10
completions/lamp.fish
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
complete -c lamp -n "__fish_use_subcommand" -s s -l set -d 'Sets brightness to given value'
|
||||||
|
complete -c lamp -n "__fish_use_subcommand" -s i -l increase -d 'Increases brightness'
|
||||||
|
complete -c lamp -n "__fish_use_subcommand" -s d -l decrease -d 'Decreases brightness'
|
||||||
|
complete -c lamp -n "__fish_use_subcommand" -s t -l type -d 'choose controller type' -r -f -a "raw lin log"
|
||||||
|
complete -c lamp -n "__fish_use_subcommand" -s g -l get -d 'Prints current brightness value'
|
||||||
|
complete -c lamp -n "__fish_use_subcommand" -s z -l zero -d 'Sets brightness to lowest value'
|
||||||
|
complete -c lamp -n "__fish_use_subcommand" -s f -l full -d 'Sets brightness to highest value'
|
||||||
|
complete -c lamp -n "__fish_use_subcommand" -s l -l list -d 'Lists all available brightness and led controllers'
|
||||||
|
complete -c lamp -n "__fish_use_subcommand" -s h -l help -d 'Prints help information'
|
||||||
|
complete -c lamp -n "__fish_use_subcommand" -s V -l version -d 'Prints version information'
|
82
src/cli.rs
Normal file
82
src/cli.rs
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
use clap::{App, Arg, ArgGroup, ArgMatches};
|
||||||
|
|
||||||
|
pub fn build_cli() -> App<'static, 'static> {
|
||||||
|
App::new("RS Light")
|
||||||
|
.version("1.0")
|
||||||
|
.author("crapStone <wewr.mc@gmail.com>")
|
||||||
|
.about("Utility to interact with backlight")
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("set")
|
||||||
|
.short("s")
|
||||||
|
.long("set")
|
||||||
|
.value_name("VALUE")
|
||||||
|
.help("Sets brightness to given value")
|
||||||
|
.takes_value(true),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("inc")
|
||||||
|
.short("i")
|
||||||
|
.long("increase")
|
||||||
|
.value_name("PERCENT")
|
||||||
|
.help("Increases brightness")
|
||||||
|
.takes_value(true),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("dec")
|
||||||
|
.short("d")
|
||||||
|
.long("decrease")
|
||||||
|
.value_name("PERCENT")
|
||||||
|
.help("Decreases brightness")
|
||||||
|
.takes_value(true),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("get")
|
||||||
|
.short("g")
|
||||||
|
.long("get")
|
||||||
|
.help("Prints current brightness value"),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("zer")
|
||||||
|
.short("z")
|
||||||
|
.long("zero")
|
||||||
|
.help("Sets brightness to lowest value"),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("ful")
|
||||||
|
.short("f")
|
||||||
|
.long("full")
|
||||||
|
.help("Sets brightness to highest value"),
|
||||||
|
)
|
||||||
|
.group(ArgGroup::with_name("brightness_control").args(&["set", "inc", "dec", "get", "zer", "ful"]))
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("list")
|
||||||
|
.short("l")
|
||||||
|
.long("list")
|
||||||
|
.help("Lists all available brightness and led controllers")
|
||||||
|
.conflicts_with_all(&["brightness_control"]),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("ctrl_type")
|
||||||
|
.short("t")
|
||||||
|
.long("type")
|
||||||
|
.value_name("controller_type")
|
||||||
|
.takes_value(true)
|
||||||
|
.possible_values(&["raw", "lin", "log"])
|
||||||
|
.default_value("lin")
|
||||||
|
.help("choose controller type")
|
||||||
|
.long_help(
|
||||||
|
r#"You can choose between these controller types:
|
||||||
|
raw: uses the raw values found in the device files
|
||||||
|
lin: uses percentage values (0.0 - 1.0) with a linear curve for the actual brightness
|
||||||
|
log: uses percentage values (0.0 - 1.0) with a logarithmic curve for the actual brightness
|
||||||
|
the perceived brightness for the human eyes should be linear with this controller
|
||||||
|
"#,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a argument parser with [clap](../clap/index.html) and returns a `Box` with the
|
||||||
|
/// [matches](../clap/struct.ArgMatches.html).
|
||||||
|
pub fn parse_args<'a>() -> Box<ArgMatches<'a>> {
|
||||||
|
Box::new(build_cli().get_matches())
|
||||||
|
}
|
204
src/controllers.rs
Normal file
204
src/controllers.rs
Normal file
|
@ -0,0 +1,204 @@
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::fs::{File, OpenOptions};
|
||||||
|
use std::io::prelude::*;
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
use std::process::exit;
|
||||||
|
|
||||||
|
use exitcode;
|
||||||
|
|
||||||
|
const SYS_PATHS: [&str; 2] = ["/sys/class/backlight", "/sys/class/leds"];
|
||||||
|
|
||||||
|
pub trait Controller {
|
||||||
|
fn get_brightness(&self) -> i32;
|
||||||
|
fn get_max_brightness(&self) -> i32;
|
||||||
|
fn set_brightness(&self, value: i32);
|
||||||
|
|
||||||
|
fn check_brightness_value(&self, value: i32) {
|
||||||
|
if value > self.get_max_brightness() {
|
||||||
|
eprintln!(
|
||||||
|
"brightness value too high: {} > {}",
|
||||||
|
value,
|
||||||
|
self.get_max_brightness()
|
||||||
|
);
|
||||||
|
exit(exitcode::DATAERR);
|
||||||
|
} else if value < 0 {
|
||||||
|
eprintln!("brightness value too low: {}", value);
|
||||||
|
exit(exitcode::DATAERR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct RawController {
|
||||||
|
path: Box<PathBuf>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RawController {
|
||||||
|
pub fn new(path: Box<PathBuf>) -> Self {
|
||||||
|
Self { path: path }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Controller for RawController {
|
||||||
|
fn get_brightness(&self) -> i32 {
|
||||||
|
read_file_to_int(self.path.join("brightness"))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_max_brightness(&self) -> i32 {
|
||||||
|
read_file_to_int(self.path.join("max_brightness"))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_brightness(&self, value: i32) {
|
||||||
|
self.check_brightness_value(value);
|
||||||
|
|
||||||
|
let path = self.path.join("brightness");
|
||||||
|
|
||||||
|
let mut file = match OpenOptions::new().write(true).read(true).open(&path) {
|
||||||
|
Err(why) => {
|
||||||
|
eprintln!("couldn't open '{}': {:?}", &path.display(), why.kind());
|
||||||
|
exit(exitcode::OSFILE);
|
||||||
|
}
|
||||||
|
Ok(file) => file,
|
||||||
|
};
|
||||||
|
|
||||||
|
match write!(file, "{}", value) {
|
||||||
|
Ok(_) => {}
|
||||||
|
Err(err) => {
|
||||||
|
eprintln!(
|
||||||
|
"could not write '{}' to file '{}': {:?}",
|
||||||
|
value,
|
||||||
|
&path.display(),
|
||||||
|
err.kind()
|
||||||
|
);
|
||||||
|
exit(exitcode::OSFILE);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct LinController {
|
||||||
|
parent_controller: RawController,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LinController {
|
||||||
|
pub fn new(path: Box<PathBuf>) -> Self {
|
||||||
|
Self {
|
||||||
|
parent_controller: RawController::new(path),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Controller for LinController {
|
||||||
|
fn get_brightness(&self) -> i32 {
|
||||||
|
((self.parent_controller.get_brightness() as f64
|
||||||
|
/ self.parent_controller.get_max_brightness() as f64)
|
||||||
|
* self.get_max_brightness() as f64) as i32
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_max_brightness(&self) -> i32 {
|
||||||
|
100
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_brightness(&self, value: i32) {
|
||||||
|
self.check_brightness_value(value);
|
||||||
|
|
||||||
|
if value > self.get_max_brightness() {
|
||||||
|
eprintln!(
|
||||||
|
"brightness value too high! {} > {}",
|
||||||
|
value,
|
||||||
|
self.get_max_brightness()
|
||||||
|
);
|
||||||
|
exit(exitcode::DATAERR);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.parent_controller.set_brightness(
|
||||||
|
(value * self.parent_controller.get_max_brightness()) / self.get_max_brightness(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct LogController {
|
||||||
|
parent_controller: RawController,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LogController {
|
||||||
|
pub fn new(path: Box<PathBuf>) -> Self {
|
||||||
|
Self {
|
||||||
|
parent_controller: RawController::new(path),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Controller for LogController {
|
||||||
|
fn get_brightness(&self) -> i32 {
|
||||||
|
((self.parent_controller.get_brightness() as f64).log10()
|
||||||
|
/ (self.parent_controller.get_max_brightness() as f64).log10()
|
||||||
|
* self.get_max_brightness() as f64) as i32
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_max_brightness(&self) -> i32 {
|
||||||
|
100
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_brightness(&self, value: i32) {
|
||||||
|
self.check_brightness_value(value);
|
||||||
|
|
||||||
|
if value > self.get_max_brightness() {
|
||||||
|
eprintln!(
|
||||||
|
"brightness value too high! {} > {}",
|
||||||
|
value,
|
||||||
|
self.get_max_brightness()
|
||||||
|
);
|
||||||
|
exit(exitcode::DATAERR);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.parent_controller.set_brightness(10f64.powf(
|
||||||
|
(value as f64 / self.get_max_brightness() as f64)
|
||||||
|
* (self.parent_controller.get_max_brightness() as f64).log10(),
|
||||||
|
) as i32)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_file_to_int(path: PathBuf) -> i32 {
|
||||||
|
let mut file = match File::open(&path) {
|
||||||
|
Err(why) => {
|
||||||
|
eprintln!("couldn't open {}: {:?}", path.display(), why.kind());
|
||||||
|
exit(exitcode::OSFILE);
|
||||||
|
}
|
||||||
|
Ok(file) => file,
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut s = String::new();
|
||||||
|
match file.read_to_string(&mut s) {
|
||||||
|
Err(why) => {
|
||||||
|
eprintln!("couldn't read {}: {:?}", path.display(), why.kind());
|
||||||
|
exit(exitcode::OSFILE);
|
||||||
|
}
|
||||||
|
Ok(_) => return s.trim().parse().unwrap(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Searches through all paths in `SYS_PATHS` and creates a `HashMap` with the name and absolute path.
|
||||||
|
///
|
||||||
|
/// It returns a `Tuple` of the default backlight name and the `HashMap`.
|
||||||
|
pub fn get_controllers() -> (String, HashMap<String, Box<PathBuf>>) {
|
||||||
|
let mut controllers: HashMap<String, Box<PathBuf>> = HashMap::new();
|
||||||
|
|
||||||
|
let mut default = None;
|
||||||
|
|
||||||
|
for path in SYS_PATHS.iter() {
|
||||||
|
if Path::new(path).exists() {
|
||||||
|
for name in Path::new(path).read_dir().unwrap() {
|
||||||
|
let name = name.unwrap().path();
|
||||||
|
let key = String::from(name.file_name().unwrap().to_str().unwrap());
|
||||||
|
|
||||||
|
if default.is_none() {
|
||||||
|
default = Some(key.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
controllers.insert(key, Box::new(name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(default.unwrap(), controllers)
|
||||||
|
}
|
61
src/main.rs
Normal file
61
src/main.rs
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
mod cli;
|
||||||
|
mod controllers;
|
||||||
|
|
||||||
|
use std::process::exit;
|
||||||
|
|
||||||
|
use exitcode;
|
||||||
|
|
||||||
|
use controllers::{Controller, LinController, LogController, RawController};
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let matches = cli::parse_args();
|
||||||
|
|
||||||
|
let (default_ctrl, ctrls) = controllers::get_controllers();
|
||||||
|
|
||||||
|
let p = ctrls.get(&default_ctrl).unwrap().to_owned();
|
||||||
|
let controller: Box<dyn Controller> = match matches.value_of("ctrl_type") {
|
||||||
|
Some("raw") => Box::new(RawController::new(p)),
|
||||||
|
Some("lin") => Box::new(LinController::new(p)),
|
||||||
|
Some("log") => Box::new(LogController::new(p)),
|
||||||
|
Some(_) | None => panic!(ERROR_MSG),
|
||||||
|
};
|
||||||
|
|
||||||
|
if matches.is_present("list") {
|
||||||
|
for ctrl in ctrls.keys() {
|
||||||
|
println!("{}", ctrl);
|
||||||
|
}
|
||||||
|
exit(exitcode::OK);
|
||||||
|
} else if let Some(value) = matches.value_of("set") {
|
||||||
|
let new_value = value.parse::<i32>().unwrap();
|
||||||
|
controller.set_brightness(new_value);
|
||||||
|
} else if let Some(value) = matches.value_of("inc") {
|
||||||
|
let new_value = controller.get_brightness() + value.parse::<i32>().unwrap();
|
||||||
|
controller.set_brightness(new_value.min(controller.get_max_brightness()));
|
||||||
|
} else if let Some(value) = matches.value_of("dec") {
|
||||||
|
let new_value = controller.get_brightness() - value.parse::<i32>().unwrap();
|
||||||
|
controller.set_brightness(new_value.max(0));
|
||||||
|
} else if matches.is_present("get") {
|
||||||
|
println!("{}", controller.get_brightness());
|
||||||
|
} else if matches.is_present("zer") {
|
||||||
|
controller.set_brightness(0);
|
||||||
|
} else if matches.is_present("ful") {
|
||||||
|
controller.set_brightness(controller.get_max_brightness());
|
||||||
|
} else {
|
||||||
|
panic!(ERROR_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
exit(exitcode::OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://xkcd.com/2200/
|
||||||
|
const ERROR_MSG: &str = r#"
|
||||||
|
ERROR!
|
||||||
|
|
||||||
|
If you're seeing this, the code is in what I thought was an unreachable state.
|
||||||
|
|
||||||
|
I could give you advice for what to do. but honestly, why should you trust me?
|
||||||
|
I clearly screwed this up. I'm writing a message that should never appear,
|
||||||
|
yet I know it will probably appear someday.
|
||||||
|
|
||||||
|
On a deep level, I know I'm not up to this task. I'm so sorry.
|
||||||
|
"#;
|
Loading…
Reference in a new issue