backlight_control_rs/
lib.rs

1//! This lib allows for simple adjustment of the users backlight.
2use std::{
3    cmp::{max, min},
4    fs,
5    path::PathBuf,
6};
7
8pub mod error;
9
10pub use error::*;
11
12const BRIGHTNESS_BASE_PATH: &str = "/sys/class/backlight";
13
14/// Internal function to get the path of the backlight
15///
16/// This is different from system to system, since it depends on the GPU.
17fn vendor_path() -> Result<PathBuf> {
18    let vendor_dir = fs::read_dir(BRIGHTNESS_BASE_PATH)?
19        .filter_map(std::io::Result::ok) // Filter out any errors
20        .next() // Get the first entry
21        .ok_or(Error::FailedToGetFirstEntry)?
22        .file_name(); // Get the file name directly
23
24    Ok(PathBuf::from(BRIGHTNESS_BASE_PATH).join(vendor_dir))
25}
26
27/// Gets the max brightness
28///
29/// ## Panics
30///
31/// Will only panic if it cannot parse the value in in the `max_brightness` file. This should never
32/// happen. If it does this is an OS error.
33pub fn get_max_brightness() -> Result<u32> {
34    let max_brightness_path = vendor_path()?.join("max_brightness");
35
36    Ok(fs::read_to_string(&max_brightness_path)?
37        .trim()
38        .parse()
39        .expect("Failed to parse max brightness. This should never happen."))
40}
41
42/// Gets the current brightness
43///
44/// ## Panics
45///
46/// Will only panic if it cannot parse the value in in the `brightness` file. This should never
47/// happen. If it does this is an OS error.
48pub fn get_brightness() -> Result<u32> {
49    let brightness_path = vendor_path()?.join("brightness");
50
51    Ok(fs::read_to_string(&brightness_path)?
52        .trim()
53        .parse()
54        .expect("Failed to parse brightness. This should never happen."))
55}
56
57/// Attempts to set the brightness
58///
59/// This will fail if you lack the proper permissions.
60pub fn set_brightness(value: u32) -> Result<()> {
61    let brightness_path = vendor_path()?.join("brightness");
62
63    fs::write(
64        brightness_path,
65        min(value, get_max_brightness()?).to_string(),
66    )?;
67
68    Ok(())
69}
70
71/// Convenience wrapper around set_brightness for adjusting relative to the current value
72///
73/// # Parameters
74///
75/// - `value`: The value to adjust by.
76///
77/// - `percentage`: Will treat the value as a percentage to adjust by, rather than an absolute value.
78pub fn adjust_brightness_relative(value: i32, percentage: bool) -> Result<()> {
79    let brightness: i32 = get_brightness()?.try_into().unwrap();
80
81    if percentage {
82        let max_brightness: i32 = get_max_brightness()?.try_into().unwrap();
83
84        let new_brightness: u32 = (max_brightness * value / 100 + brightness).max(0) as u32;
85
86        set_brightness(new_brightness)?;
87
88        return Ok(());
89    }
90
91    let new_brightness: i32 = brightness + value;
92
93    set_brightness(max(0, new_brightness).try_into().unwrap())
94}
95
96/// Convenience wrapper around set_brightness for setting absolute values
97///
98/// ## Parameters
99///
100/// - `value`: The value to set to.
101///
102/// - `percentage`: Will treat the value as a percentage of the max to set to, rather than an absolute value.
103pub fn adjust_brightness_absolute(value: u32, percentage: bool) -> Result<()> {
104    if percentage {
105        let max_brightness: u32 = get_max_brightness()?;
106
107        let new_brightness: u32 = max_brightness * value / 100;
108
109        set_brightness(new_brightness)?;
110
111        return Ok(());
112    }
113
114    set_brightness(value)
115}