#[rustfmt::skip]
mod gen;
pub mod manager;
pub mod service;
pub mod technology;
use dbus;
use dbus::arg::{cast, RefArg, Variant};
use std::borrow::Cow;
use std::collections::HashMap;
use std::str::FromStr;
type RefArgMap = HashMap<String, Variant<Box<dyn RefArg + 'static>>>;
type RefArgMapRef<'a> = HashMap<String, &'a dyn RefArg>;
type RefArgIter<'a> = Box<dyn Iterator<Item=&'a dyn RefArg> + 'a>;
#[derive(Debug, Fail)]
pub enum Error {
#[fail(display = "{}", _0)]
DbusError(#[cause] dbus::Error),
#[fail(display = "'{}'", _0)]
PropertyError(#[cause] PropertyError),
}
#[derive(Debug, Fail)]
pub enum PropertyError {
#[fail(display = "Property not present: '{}'", _0)]
NotPresent(Cow<'static, str>),
#[fail(display = "Failed to cast property: '{}'", _0)]
Cast(Cow<'static, str>)
}
impl From<PropertyError> for Error {
fn from(e: PropertyError) -> Self {
Error::PropertyError(e)
}
}
impl From<dbus::Error> for Error {
fn from(e: dbus::Error) -> Self {
Error::DbusError(e)
}
}
fn get_property<T: Clone + 'static>(
properties: &RefArgMap,
prop_name: &'static str,
) -> Result<T, PropertyError> {
properties.get(prop_name)
.ok_or_else(|| PropertyError::NotPresent(Cow::Borrowed(prop_name)))
.and_then(|variant|
cast::<T>(&variant.0).cloned()
.ok_or_else(|| PropertyError::Cast(Cow::Borrowed(prop_name)))
)
}
fn get_property_fromstr<T: FromStr + 'static>(
properties: &RefArgMap,
prop_name: &'static str,
) -> Result<T, PropertyError> {
properties.get(prop_name)
.ok_or_else(|| PropertyError::NotPresent(Cow::Borrowed(prop_name)))
.and_then(|variant| variant.as_str()
.and_then(|s| T::from_str(s).ok())
.ok_or_else(|| PropertyError::Cast(Cow::Borrowed(prop_name)))
)
}
fn get_property_argiter<'a>(
properties: &'a RefArgMap,
prop_name: &'static str,
) -> Result<RefArgIter<'a>, PropertyError> {
properties.get(prop_name)
.ok_or_else(|| PropertyError::NotPresent(Cow::Borrowed(prop_name)))
.and_then(|variant|
variant.0.as_iter()
.ok_or_else(|| PropertyError::Cast(Cow::Borrowed(prop_name)))
)
}
pub trait FromProperties: Sized {
fn from_properties(properties: &RefArgMap, prop_name: &'static str) -> Result<Self, PropertyError>;
}
impl FromProperties for String {
fn from_properties(properties: &RefArgMap, prop_name: &'static str) -> Result<Self, PropertyError> {
get_property_fromstr::<Self>(properties, prop_name)
}
}
impl <T: FromProperties + Clone + 'static> FromProperties for Vec<T> {
fn from_properties(properties: &RefArgMap, prop_name: &'static str) -> Result<Self, PropertyError> {
get_property::<Vec<T>>(properties, prop_name)
}
}
impl FromProperties for u8 {
fn from_properties(properties: &RefArgMap, prop_name: &'static str) -> Result<Self, PropertyError> {
get_property::<Self>(properties, prop_name)
}
}
impl FromProperties for bool {
fn from_properties(properties: &RefArgMap, prop_name: &'static str) -> Result<Self, PropertyError> {
get_property::<Self>(properties, prop_name)
}
}
impl <T: FromProperties> FromProperties for Option<T> {
fn from_properties(properties: &RefArgMap, prop_name: &'static str) -> Result<Self, PropertyError> {
match T::from_properties(properties, prop_name) {
Err(PropertyError::NotPresent(_)) => Ok(None),
Ok(s) => Ok(Some(s)),
res => res.map(Option::Some),
}
}
}