1use super::{MethodType, DataType, MTFn, MTFnMut, MTSync, MethodResult, MethodInfo};
2use super::{Tree, ObjectPath, Interface, Property, Signal, Method};
3use super::objectpath::IfaceCache;
4use std::sync::Arc;
5use dbus::strings::{Interface as IfaceName, Member};
6use dbus::{Path, arg};
7use std::cell::RefCell;
8
9#[derive(Debug, Clone)]
22pub struct Factory<M: MethodType<D>, D: DataType=()>(Arc<IfaceCache<M, D>>);
23
24impl<M: MethodType<D>, D: DataType> From<Arc<IfaceCache<M, D>>> for Factory<M, D> {
25 fn from(f: Arc<IfaceCache<M, D>>) -> Self { Factory(f) }
26}
27
28impl Factory<MTFn<()>, ()> {
29 pub fn new_fn<D: DataType>() -> Factory<MTFn<D>, D> { Factory(IfaceCache::new()) }
31
32 pub fn new_fnmut<D: DataType>() -> Factory<MTFnMut<D>, D> { Factory(IfaceCache::new()) }
34
35 pub fn new_sync<D: DataType>() -> Factory<MTSync<D>, D> { Factory(IfaceCache::new()) }
37
38}
39
40impl<D: DataType> Factory<MTFn<D>, D> {
41 pub fn method<H, T>(&self, t: T, data: D::Method, handler: H) -> Method<MTFn<D>, D>
43 where H: 'static + Fn(&MethodInfo<MTFn<D>, D>) -> MethodResult, T: Into<Member<'static>> {
44 super::leaves::new_method(t.into(), data, Box::new(handler) as Box<_>)
45 }
46}
47
48impl<D: DataType> Factory<MTFnMut<D>, D> {
49 pub fn method<H, T>(&self, t: T, data: D::Method, handler: H) -> Method<MTFnMut<D>, D>
51 where H: 'static + FnMut(&MethodInfo<MTFnMut<D>, D>) -> MethodResult, T: Into<Member<'static>> {
52 super::leaves::new_method(t.into(), data, Box::new(RefCell::new(handler)) as Box<_>)
53 }
54}
55
56impl<D: DataType> Factory<MTSync<D>, D> {
57 pub fn method<H, T>(&self, t: T, data: D::Method, handler: H) -> Method<MTSync<D>, D>
59 where H: Fn(&MethodInfo<MTSync<D>, D>) -> MethodResult + Send + Sync + 'static, T: Into<Member<'static>> {
60 super::leaves::new_method(t.into(), data, Box::new(handler) as Box<_>)
61 }
62}
63
64
65impl<M: MethodType<D>, D: DataType> Factory<M, D> {
66
67 pub fn property<A: arg::Arg, T: Into<String>>(&self, name: T, data: D::Property) -> Property<M, D> {
71 let sig = A::signature();
72 super::leaves::new_property(name.into(), sig, data)
73 }
74
75 pub fn signal<T: Into<Member<'static>>>(&self, name: T, data: D::Signal) -> Signal<D> {
77 super::leaves::new_signal(name.into(), data)
78 }
79
80 pub fn interface<T: Into<IfaceName<'static>>>(&self, name: T, data: D::Interface) -> Interface<M, D> {
82 super::objectpath::new_interface(name.into(), data)
83 }
84
85 pub fn object_path<T: Into<Path<'static>>>(&self, name: T, data: D::ObjectPath) -> ObjectPath<M, D> {
87 super::objectpath::new_objectpath(name.into(), data, self.0.clone())
88 }
89
90 pub fn tree(&self, data: D::Tree) -> Tree<M, D> {
92 super::objectpath::new_tree(data)
93 }
94
95 pub fn method_sync<H, T>(&self, t: T, data: D::Method, handler: H) -> Method<M, D>
99 where H: Fn(&MethodInfo<M, D>) -> MethodResult + Send + Sync + 'static, T: Into<Member<'static>> {
100 super::leaves::new_method(t.into(), data, M::make_method(handler))
101 }
102}
103
104
105#[test]
106fn create_fnmut() {
107 let f = Factory::new_fnmut::<()>();
108 let mut move_me = 5u32;
109 let m = f.method("test", (), move |m| {
110 move_me += 1;
111 Ok(vec!(m.msg.method_return().append1(&move_me)))
112 });
113 assert_eq!(&**m.get_name(), "test");
114}
115
116
117#[test]
118fn fn_customdata() {
119 #[derive(Default)]
120 struct Custom;
121 impl DataType for Custom {
122 type Tree = ();
123 type ObjectPath = Arc<u8>;
124 type Interface = ();
125 type Property = ();
126 type Method = i32;
127 type Signal = ();
128 }
129
130 let f = Factory::new_fn::<Custom>();
131
132 let m = f.method("test", 789, |_| unimplemented!());
133 assert_eq!(*m.get_data(), 789);
134
135 let o = f.object_path("/test/test", Arc::new(7));
136 assert_eq!(**o.get_data(), 7);
137}