diff options
Diffstat (limited to 'third_party/rust/dbus/src/crossroads/handlers.rs')
-rw-r--r-- | third_party/rust/dbus/src/crossroads/handlers.rs | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/third_party/rust/dbus/src/crossroads/handlers.rs b/third_party/rust/dbus/src/crossroads/handlers.rs new file mode 100644 index 0000000000..2d466ba119 --- /dev/null +++ b/third_party/rust/dbus/src/crossroads/handlers.rs @@ -0,0 +1,138 @@ +use std::{fmt, cell}; +use std::any::Any; +use crate::arg::ArgBuilder; +use crate::{Path as PathName, Interface as IfaceName, Member as MemberName, Signature, Message, arg}; +use super::crossroads::{Crossroads, PathData, MLookup}; +use super::info::{MethodInfo, PropInfo}; +use super::MethodErr; + +pub struct DebugMethod<H: Handlers>(pub H::Method); +impl<H: Handlers> fmt::Debug for DebugMethod<H> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "...") } +} + +pub struct DebugProp<H: Handlers>(pub Option<H::GetProp>, pub Option<H::SetProp>); +impl<H: Handlers> fmt::Debug for DebugProp<H> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "...") } +} + +pub trait Handlers { + type Method; + type GetProp; + type SetProp; + type Iface; +} + +/// Parallel tree - Par +#[derive(Debug, Clone, Copy, Default)] +pub struct Par; + +impl Par { + pub fn typed_getprop<I: 'static, T: arg::Arg + arg::Append, G>(getf: G) -> <Par as Handlers>::GetProp + where G: Fn(&I, &ParInfo) -> Result<T, MethodErr> + Send + Sync + 'static { + Box::new(move |data, ia, info| { + let iface: &I = data.downcast_ref().unwrap(); + let t = getf(iface, info)?; + ia.append(t); + Ok(()) + }) + } + + pub fn typed_setprop<I: 'static, T: arg::Arg + for <'z> arg::Get<'z>, S>(setf: S) -> <Par as Handlers>::SetProp + where S: Fn(&I, &ParInfo, T) -> Result<(), MethodErr> + Send + Sync + 'static { + Box::new(move |data, ii, info| { + let iface: &I = data.downcast_ref().unwrap(); + let t: T = ii.read()?; + setf(iface, info, t) + }) + } +} + +#[derive(Debug)] +pub struct ParInfo<'a> { + lookup: MLookup<'a, Par>, + message: &'a Message, +} + +impl<'a> ParInfo<'a> { + pub fn msg(&self) -> &Message { self.message } + pub (super) fn new(msg: &'a Message, lookup: MLookup<'a, Par>) -> Self { + ParInfo { lookup, message: msg } + } + pub fn path_data(&self) -> &PathData<Par> { self.lookup.data } + pub fn crossroads(&self) -> &Crossroads<Par> { self.lookup.cr } +} + +impl Handlers for Par { + type Method = Box<Fn(&(dyn Any + Send + Sync), &ParInfo) -> Option<Message> + Send + Sync + 'static>; + type GetProp = Box<Fn(&(dyn Any + Send + Sync), &mut arg::IterAppend, &ParInfo) -> Result<(), MethodErr> + Send + Sync + 'static>; + type SetProp = Box<Fn(&(dyn Any + Send + Sync), &mut arg::Iter, &ParInfo) -> Result<(), MethodErr> + Send + Sync + 'static>; + type Iface = Box<dyn Any + 'static + Send + Sync>; +} + +impl MethodInfo<'_, Par> { + pub fn new_par<N, F, T>(name: N, f: F) -> Self where + F: Fn(&T, &ParInfo) -> Result<Option<Message>, MethodErr> + Send + Sync + 'static, + N: Into<MemberName<'static>>, + T: Any + Send + Sync + 'static, + { + Self::new(name.into(), Box::new(move |data, info| { + let x = data.downcast_ref().unwrap(); + f(x, info).unwrap_or_else(|e| { Some(e.to_message(info.message)) }) + })) + } +} + + +/// Mutable, non-Send tree +#[derive(Debug, Clone, Copy, Default)] +pub struct Mut; + +#[derive(Debug)] +pub struct MutCtx<'a> { + message: &'a Message, + send_extra: cell::RefCell<Vec<Message>>, +} + +impl<'a> MutCtx<'a> { + pub fn msg(&self) -> &Message { self.message } + pub fn send(&self, msg: Message) { self.send_extra.borrow_mut().push(msg); } + pub (super) fn new(msg: &'a Message) -> Self { MutCtx { message: msg, send_extra: Default::default() } } +} + +impl Handlers for Mut { + type Method = MutMethod; + type GetProp = Box<FnMut(&mut (dyn Any), &mut arg::IterAppend, &MutCtx) -> Result<(), MethodErr> + 'static>; + type SetProp = Box<FnMut(&mut (dyn Any), &mut arg::Iter, &MutCtx) -> Result<(), MethodErr> + 'static>; + type Iface = Box<dyn Any>; +} + + +pub struct MutMethod(pub (super) MutMethods); + +pub (super) enum MutMethods { + MutIface(Box<FnMut(&mut (dyn Any), &MutCtx) -> Option<Message> + 'static>), +// Info(Box<FnMut(&(dyn Any), &Message, &Path) -> Option<Message> + 'static>), +// MutCr(fn(&mut Crossroads<Mut>, &Message) -> Vec<Message>), +} + +impl Mut { + pub fn typed_method_iface<IA: ArgBuilder, OA: ArgBuilder, I: 'static, F>(mut f: F) -> <Mut as Handlers>::Method + where F: FnMut(&mut I, &MutCtx, IA) -> Result<OA, MethodErr> + 'static { + MutMethod(MutMethods::MutIface(Box::new(move |data, info| { + let iface: &mut I = data.downcast_mut().unwrap(); + let ia = match IA::read(info.msg()) { + Err(e) => return Some(MethodErr::from(e).to_message(info.msg())), + Ok(ia) => ia, + }; + match f(iface, info, ia) { + Err(e) => Some(e.to_message(info.msg())), + Ok(r) => { + let mut m = info.msg().method_return(); + OA::append(r, &mut m); + Some(m) + }, + } + }))) + } +} |