1use std::fmt;
4use dbus::Message;
5use dbus::ffidisp::stdintf;
6use dbus::arg::{Iter, IterAppend};
7use std::marker::PhantomData;
8use super::{Method, Interface, Property, ObjectPath, Tree};
9use std::cell::RefCell;
10use dbus::MethodErr;
11
12pub type MethodResult = Result<Vec<Message>, MethodErr>;
14
15pub trait DataType: Sized + Default {
19 type Tree: fmt::Debug;
21 type ObjectPath: fmt::Debug;
23 type Property: fmt::Debug;
25 type Interface: fmt::Debug;
27 type Method: fmt::Debug;
29 type Signal: fmt::Debug;
31}
32
33impl DataType for () {
35 type Tree = ();
36 type ObjectPath = ();
37 type Interface = ();
38 type Property = ();
39 type Method = ();
40 type Signal = ();
41}
42
43pub trait MethodType<D: DataType>: Sized + Default {
47 type Method: ?Sized;
49 type GetProp: ?Sized;
51 type SetProp: ?Sized;
53
54 fn call_getprop(_: &Self::GetProp, _: &mut IterAppend, _: &PropInfo<Self, D>) -> Result<(), MethodErr>;
56 fn call_setprop(_: &Self::SetProp, _: &mut Iter, _: &PropInfo<Self, D>) -> Result<(), MethodErr>;
58 fn call_method(_: &Self::Method, _: &MethodInfo<Self, D>) -> MethodResult;
60
61 fn make_getprop<H>(h: H) -> Box<Self::GetProp>
63 where H: Fn(&mut IterAppend, &PropInfo<Self,D>) -> Result<(), MethodErr> + Send + Sync + 'static;
64 fn make_method<H>(h: H) -> Box<Self::Method>
66 where H: Fn(&MethodInfo<Self,D>) -> MethodResult + Send + Sync + 'static;
67}
68
69
70#[derive(Default, Debug, Copy, Clone)]
72pub struct MTFn<D=()>(PhantomData<*const D>);
73
74impl<D: DataType> MethodType<D> for MTFn<D> {
75 type GetProp = dyn Fn(&mut IterAppend, &PropInfo<Self, D>) -> Result<(), MethodErr>;
76 type SetProp = dyn Fn(&mut Iter, &PropInfo<Self, D>) -> Result<(), MethodErr>;
77 type Method = dyn Fn(&MethodInfo<Self, D>) -> MethodResult;
78
79 fn call_getprop(p: &Self::GetProp, i: &mut IterAppend, pinfo: &PropInfo<Self, D>)
80 -> Result<(), MethodErr> { p(i, pinfo) }
81 fn call_setprop(p: &Self::SetProp, i: &mut Iter, pinfo: &PropInfo<Self, D>)
82 -> Result<(), MethodErr> { p(i, pinfo) }
83 fn call_method(p: &Self::Method, minfo: &MethodInfo<Self, D>)
84 -> MethodResult { p(minfo) }
85
86 fn make_getprop<H>(h: H) -> Box<Self::GetProp>
87 where H: Fn(&mut IterAppend, &PropInfo<Self,D>) -> Result<(), MethodErr> + Send + Sync + 'static { Box::new(h) }
88 fn make_method<H>(h: H) -> Box<Self::Method>
89 where H: Fn(&MethodInfo<Self,D>) -> MethodResult + Send + Sync + 'static { Box::new(h) }
90}
91
92#[derive(Default, Debug, Copy, Clone)]
94pub struct MTFnMut<D=()>(PhantomData<*const D>);
95
96impl<D: DataType> MethodType<D> for MTFnMut<D> {
97 type GetProp = RefCell<dyn FnMut(&mut IterAppend, &PropInfo<Self, D>) -> Result<(), MethodErr>>;
98 type SetProp = RefCell<dyn FnMut(&mut Iter, &PropInfo<Self, D>) -> Result<(), MethodErr>>;
99 type Method = RefCell<dyn FnMut(&MethodInfo<Self, D>) -> MethodResult>;
100
101 fn call_getprop(p: &Self::GetProp, i: &mut IterAppend, pinfo: &PropInfo<Self, D>)
102 -> Result<(), MethodErr> { (&mut *p.borrow_mut())(i, pinfo) }
103 fn call_setprop(p: &Self::SetProp, i: &mut Iter, pinfo: &PropInfo<Self, D>)
104 -> Result<(), MethodErr> { (&mut *p.borrow_mut())(i, pinfo) }
105 fn call_method(p: &Self::Method, minfo: &MethodInfo<Self, D>)
106 -> MethodResult { (&mut *p.borrow_mut())(minfo) }
107
108 fn make_getprop<H>(h: H) -> Box<Self::GetProp>
109 where H: Fn(&mut IterAppend, &PropInfo<Self,D>) -> Result<(), MethodErr> + Send + Sync + 'static { Box::new(RefCell::new(h)) }
110 fn make_method<H>(h: H) -> Box<Self::Method>
111 where H: Fn(&MethodInfo<Self,D>) -> MethodResult + Send + Sync + 'static { Box::new(RefCell::new(h)) }
112
113}
114
115#[derive(Default, Debug, Copy, Clone)]
117pub struct MTSync<D=()>(PhantomData<*const D>);
118
119impl<D: DataType> MethodType<D> for MTSync<D> {
120 type GetProp = dyn Fn(&mut IterAppend, &PropInfo<Self, D>) -> Result<(), MethodErr> + Send + Sync + 'static;
121 type SetProp = dyn Fn(&mut Iter, &PropInfo<Self, D>) -> Result<(), MethodErr> + Send + Sync + 'static;
122 type Method = dyn Fn(&MethodInfo<Self, D>) -> MethodResult + Send + Sync + 'static;
123
124 fn call_getprop(p: &Self::GetProp, i: &mut IterAppend, pinfo: &PropInfo<Self, D>)
125 -> Result<(), MethodErr> { p(i, pinfo) }
126 fn call_setprop(p: &Self::SetProp, i: &mut Iter, pinfo: &PropInfo<Self, D>)
127 -> Result<(), MethodErr> { p(i, pinfo) }
128 fn call_method(p: &Self::Method, minfo: &MethodInfo<Self, D>)
129 -> MethodResult { p(minfo) }
130
131 fn make_getprop<H>(h: H) -> Box<Self::GetProp>
132 where H: Fn(&mut IterAppend, &PropInfo<Self,D>) -> Result<(), MethodErr> + Send + Sync + 'static { Box::new(h) }
133 fn make_method<H>(h: H) -> Box<Self::Method>
134 where H: Fn(&MethodInfo<Self,D>) -> MethodResult + Send + Sync + 'static { Box::new(h) }
135}
136
137
138
139#[derive(Debug, Copy, Clone)]
140pub struct MethodInfo<'a, M: 'a + MethodType<D>, D: 'a + DataType> {
142 pub msg: &'a Message,
144 pub method: &'a Method<M, D>,
146 pub iface: &'a Interface<M, D>,
148 pub path: &'a ObjectPath<M, D>,
150 pub tree: &'a Tree<M, D>,
152}
153
154impl<'a, M: 'a + MethodType<D>, D: 'a + DataType> MethodInfo<'a, M, D> {
155 pub fn to_prop_info(&self, iface: &'a Interface<M, D>, prop: &'a Property<M, D>) -> PropInfo<'a, M, D> {
157 PropInfo { msg: self.msg, method: self.method, iface: iface, prop: prop, path: self.path, tree: self.tree }
158 }
159}
160
161
162impl<'a, M: 'a + MethodType<D>, D: 'a + DataType> stdintf::OrgFreedesktopDBusIntrospectable for MethodInfo<'a, M, D> {
163 type Err = MethodErr;
164 fn introspect(&self) -> Result<String, Self::Err> { Ok(self.path.introspect(self.tree)) }
165}
166
167pub fn org_freedesktop_dbus_introspectable_server<M, D>(factory: &super::Factory<M, D>, data: D::Interface) -> super::Interface<M, D>
169where
170 D: super::DataType,
171 D::Method: Default,
172 M: MethodType<D>,
173{
174 let i = factory.interface("org.freedesktop.DBus.Introspectable", data);
175 let h = move |minfo: &super::MethodInfo<M, D>| {
176 let d: &dyn stdintf::OrgFreedesktopDBusIntrospectable<Err=super::MethodErr> = minfo;
177 let arg0 = d.introspect()?;
178 let rm = minfo.msg.method_return();
179 let rm = rm.append1(arg0);
180 Ok(vec!(rm))
181 };
182 let m = factory.method_sync("Introspect", Default::default(), h);
183 let m = m.out_arg(("xml_data", "s"));
184 i.add_m(m)
185}
186
187#[derive(Debug, Copy, Clone)]
188pub struct PropInfo<'a, M: 'a + MethodType<D>, D: 'a + DataType> {
190 pub msg: &'a Message,
192 pub method: &'a Method<M, D>,
194 pub prop: &'a Property<M, D>,
196 pub iface: &'a Interface<M, D>,
198 pub path: &'a ObjectPath<M, D>,
200 pub tree: &'a Tree<M, D>,
202}
203
204impl<'a, M: 'a + MethodType<D>, D: 'a + DataType> PropInfo<'a, M, D> {
205 pub fn to_method_info(&self) -> MethodInfo<'a, M, D> {
207 MethodInfo { msg: self.msg, method: self.method, iface: self.iface, path: self.path, tree: self.tree }
208 }
209}