@@ 1,21 1,21 @@
use std::collections::HashMap;
+use anyhow::{Context, Result};
use clap::value_t;
-use failure::format_err;
-// Application configuration
+/// Application configuration
#[derive(Debug)]
struct AppConfig {
- // Which main action to complete. One for each subcommand.
+ /// Which main action to complete. One for each subcommand.
action: Action,
- // If non-empty, a list of device names to limit operations to.
+ /// If non-empty, a list of device names to limit operations to.
devices: Vec<String>,
- // D-Bus mode
+ /// D-Bus mode
bustype: DBusType,
- // Minimum brightness value
+ /// Minimum brightness value
minimum: Option<u32>,
}
@@ 27,18 27,23 @@ enum DBusType {
None,
}
-// The actions the main program can execute
+/// The actions the main program can execute.
#[derive(Debug)]
enum Action {
- Incr(u32), // Increment brightness by %
- Decr(u32), // Decrement brightness by %
- Set(u32), // Set brightness to absolute %
- Get, // Print curent brightness as %
- Watch, // Watch for changes
+ /// Increment brightness by %.
+ Incr(u32),
+ /// Decrement brightness by %.
+ Decr(u32),
+ /// Set brightness to absolute %.
+ Set(u32),
+ /// Print curent brightness as %.
+ Get,
+ /// Watch for changes.
+ Watch,
}
impl AppConfig {
- fn new(argv: &[String]) -> Result<AppConfig, failure::Error> {
+ fn new(argv: &[String]) -> Result<AppConfig> {
let matches = bright::cli::brightctl_app().get_matches_from(argv);
let action: Action = match matches.subcommand() {
("get", _) => Action::Get,
@@ 84,15 89,8 @@ impl AppConfig {
}
}
-fn main() {
+fn main() -> Result<()> {
let argv: Vec<String> = std::env::args().collect();
- run(argv).unwrap_or_else(|err| {
- print_error(err);
- std::process::exit(1);
- });
-}
-
-fn run(argv: Vec<String>) -> Result<(), failure::Error> {
let appcfg = AppConfig::new(&argv)?;
match appcfg.action {
Action::Get => get_brightness(appcfg),
@@ 101,14 99,7 @@ fn run(argv: Vec<String>) -> Result<(),
}
}
-fn print_error(err: failure::Error) {
- eprintln!("{}", err);
- // for cause in err.causes() {
- // eprintln!("{}", cause)
- // }
-}
-
-fn get_brightness(cfg: AppConfig) -> Result<(), failure::Error> {
+fn get_brightness(cfg: AppConfig) -> Result<()> {
match cfg.bustype {
DBusType::Auto => match get_brightness_dbus(&cfg) {
Ok(_) => Ok(()),
@@ 119,7 110,7 @@ fn get_brightness(cfg: AppConfig) -> Res
}
}
-fn get_brightness_dbus(cfg: &AppConfig) -> Result<(), failure::Error> {
+fn get_brightness_dbus(cfg: &AppConfig) -> Result<()> {
// let client = bright::dbus::Client::new(cfg.bustype, bright::dbus::BUSNAME);
let client = dbus_client(&cfg.bustype)?;
@@ 134,7 125,7 @@ fn get_brightness_dbus(cfg: &AppConfig)
Ok(())
}
-fn get_brightness_direct(cfg: &AppConfig) -> Result<(), failure::Error> {
+fn get_brightness_direct(cfg: &AppConfig) -> Result<()> {
let devices = bright::create_devices(cfg.devices.clone())?;
for dev in devices.iter() {
println!("{}/{}", dev.name(), dev.get()?);
@@ 142,7 133,7 @@ fn get_brightness_direct(cfg: &AppConfig
Ok(())
}
-fn set_brightness(cfg: AppConfig) -> Result<(), failure::Error> {
+fn set_brightness(cfg: AppConfig) -> Result<()> {
match cfg.bustype {
DBusType::Auto => match set_brightness_dbus(&cfg) {
Ok(_) => Ok(()),
@@ 153,7 144,7 @@ fn set_brightness(cfg: AppConfig) -> Res
}
}
-fn set_brightness_dbus(cfg: &AppConfig) -> Result<(), failure::Error> {
+fn set_brightness_dbus(cfg: &AppConfig) -> Result<()> {
let client = dbus_client(&cfg.bustype)?;
for objpath in client.devices()?.iter() {
let name = client.name(objpath.to_owned())?;
@@ 186,7 177,7 @@ fn set_brightness_dbus(cfg: &AppConfig)
Ok(())
}
-fn set_brightness_direct(cfg: &AppConfig) -> Result<(), failure::Error> {
+fn set_brightness_direct(cfg: &AppConfig) -> Result<()> {
let devices = bright::create_devices(cfg.devices.clone())?;
for dev in devices.iter() {
match cfg.action {
@@ 219,9 210,9 @@ fn set_brightness_direct(cfg: &AppConfig
Ok(())
}
-fn watch(_cfg: AppConfig) -> Result<(), failure::Error> {
+fn watch(_cfg: AppConfig) -> Result<()> {
let conn = dbus::Connection::get_private(dbus::BusType::Session)
- .map_err(|e| failure::err_msg(format!("Failed to create D-Bus connection: {:?}", e)))?;
+ .context("Failed to create D-Bus connection")?;
conn.add_match("type='signal',sender='be.devork.dbus.bright',interface='org.freedesktop.DBus.Properties',path_namespace='/be/devork/dbus/bright/devices',arg0='be.devork.dbus.bright.BacklightDevice'").unwrap();
loop {
for msg in conn.incoming(1000) {
@@ 241,13 232,13 @@ fn watch(_cfg: AppConfig) -> Result<(),
}
}
-// Create the D-Bus connection.
-//
-// This creates the D-Bus connection and checks the
-// be.devork.dbus.bright busname is registered, respecting the
-// DBusType to connct to the correct bus. This must not be called
-// with DBusType::None as that does not make sense.
-fn dbus_client(bustype: &DBusType) -> Result<bright::dbus::Client, failure::Error> {
+/// Create the D-Bus connection.
+///
+/// This creates the D-Bus connection and checks the
+/// `be.devork.dbus.bright` busname is registered, respecting the
+/// DBusType to connct to the correct bus. This must not be called
+/// with [DBusType::None] as that does not make sense.
+fn dbus_client(bustype: &DBusType) -> Result<bright::dbus::Client> {
if *bustype == DBusType::None {
panic!("Should not call dbus_connection with DBusType::None");
}
@@ 261,7 252,7 @@ fn dbus_client(bustype: &DBusType) -> Re
Ok(_) => return Ok(client),
Err(e) => match *bustype {
DBusType::System | DBusType::Session => {
- return Err(format_err!(
+ return Err(anyhow::anyhow!(
"{} not found on {:?}: {}",
bright::dbus::BUSNAME,
bus,
@@ 274,7 265,7 @@ fn dbus_client(bustype: &DBusType) -> Re
},
Err(e) => match *bustype {
DBusType::System | DBusType::Session => {
- return Err(format_err!("Failed to connect to {:?}: {}", bus, e))
+ return Err(anyhow::anyhow!("Failed to connect to {:?}: {}", bus, e))
}
DBusType::Auto => (),
DBusType::None => panic!("oops"),
@@ 283,13 274,13 @@ fn dbus_client(bustype: &DBusType) -> Re
match bright::dbus::Client::new(dbus::BusType::System, bright::dbus::BUSNAME) {
Ok(client) => match client.ping() {
Ok(_) => Ok(client),
- Err(e) => Err(format_err!(
+ Err(e) => Err(anyhow::anyhow!(
"{} not found on {:?}: {}",
bright::dbus::BUSNAME,
bus,
e
)),
},
- Err(e) => Err(format_err!("Failed to connect to any D-Bus bus: {}", e)),
+ Err(e) => Err(anyhow::anyhow!("Failed to connect to any D-Bus bus: {}", e)),
}
}
@@ 29,14 29,16 @@
//! ever acquire these object paths from the manager.
use std::collections::HashMap;
+use std::error::Error;
+use std::fmt;
use std::rc::Rc;
use std::sync::Arc;
use dbus::{self, stdintf::org_freedesktop_dbus::Properties};
-use failure::ResultExt;
-use failure_derive::Fail;
use log::{debug, error, info};
+use crate::error::ErrInfo;
+
// The public DBus names we use.
pub static BUSNAME: &str = "be.devork.dbus.bright";
pub static MANAGER_PATH: &str = "/be/devork/dbus/bright/manager";
@@ 619,53 621,73 @@ impl<'a> Client<'a> {
}
}
-#[derive(Debug)]
pub struct ClientError {
- inner: failure::Context<ClientErrorKind>,
+ inner: Box<ErrInfo<ClientErrorKind>>,
}
-#[derive(Copy, Clone, Eq, PartialEq, Debug, Fail)]
+#[derive(Copy, Clone, Eq, PartialEq, Debug)]
pub enum ClientErrorKind {
- #[fail(display = "The D-Bus method call return value had an unexpected type")]
BadReturnType,
- #[fail(display = "The D-Bus method call failed")]
CallFailed,
- #[fail(display = "The brightness value is out of range")]
BrightnessRange,
}
-impl failure::Fail for ClientError {
- fn cause(&self) -> Option<&dyn failure::Fail> {
- self.inner.cause()
- }
-
- fn backtrace(&self) -> Option<&failure::Backtrace> {
- self.inner.backtrace()
+impl fmt::Display for ClientErrorKind {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match self {
+ ClientErrorKind::BadReturnType => write!(
+ f,
+ "The D-Bus method call return value had an unexpected type"
+ ),
+ ClientErrorKind::CallFailed => write!(f, "The D-Bus method call failed"),
+ ClientErrorKind::BrightnessRange => write!(f, "The brightness value is out of range"),
+ }
}
}
-impl std::fmt::Display for ClientError {
- fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
- std::fmt::Display::fmt(&self.inner, f)
+impl fmt::Display for ClientError {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt::Display::fmt(&self.inner, f)
+ }
+}
+
+impl fmt::Debug for ClientError {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt::Debug::fmt(&self.inner, f)
+ }
+}
+
+impl Error for ClientError {
+ fn source(&self) -> Option<&(dyn Error + 'static)> {
+ self.inner.source()
}
}
impl ClientError {
pub fn kind(&self) -> ClientErrorKind {
- *self.inner.get_context()
+ *self.inner.data()
}
}
impl From<ClientErrorKind> for ClientError {
fn from(kind: ClientErrorKind) -> ClientError {
- ClientError {
- inner: failure::Context::new(kind),
+ Self {
+ inner: ErrInfo::boxed(kind),
}
}
}
-impl From<failure::Context<ClientErrorKind>> for ClientError {
- fn from(inner: failure::Context<ClientErrorKind>) -> ClientError {
- ClientError { inner }
+trait ResultExt<T, E> {
+ fn context(self, kind: ClientErrorKind) -> Result<T, ClientError>;
+}
+
+impl<T, E> ResultExt<T, E> for Result<T, E>
+where
+ E: std::error::Error + Send + Sync + 'static,
+{
+ fn context(self, kind: ClientErrorKind) -> Result<T, ClientError> {
+ self.map_err(|err| ClientError {
+ inner: ErrInfo::boxed_with_source(kind, err),
+ })
}
}