#[derive(Debug,Copy,Clone)] /// Errors that can happen when creating a MessageItem::Array. pubenum ArrayError { /// The array is empty.
EmptyArray, /// The array is composed of different element types.
DifferentElementTypes, /// The supplied signature is not a valid array signature
InvalidSignature,
}
/// An RAII wrapper around Fd to ensure that file descriptor is closed /// when the scope ends. #[derive(Debug, PartialEq, PartialOrd)] pubstruct OwnedFd {
fd: RawFd
}
impl OwnedFd { /// Create a new OwnedFd from a RawFd. pubfn new(fd: RawFd) -> OwnedFd {
OwnedFd { fd: fd }
}
/// Convert an OwnedFD back into a RawFd. pubfn into_fd(self) -> RawFd { let s = self.fd;
::std::mem::forget(self);
s
}
}
impl Drop for OwnedFd { fn drop(&mutself) { unsafe { libc::close(self.fd); }
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd)] /// An array of MessageItem where every MessageItem is of the same type. pubstruct MessageItemArray {
v: Vec<MessageItem>, // signature includes the "a"!
sig: Signature<'static>,
}
impl MessageItemArray { /// Creates a new array where every element has the supplied signature. /// /// Signature is the full array signature, not the signature of the element. pubfn new(v: Vec<MessageItem>, sig: Signature<'static>) -> Result<MessageItemArray, ArrayError> { let a = MessageItemArray {v: v, sig: sig }; if a.sig.as_bytes()[0] != ffi::DBUS_TYPE_ARRAY as u8 { return Err(ArrayError::InvalidSignature) }
{ let esig = a.element_signature(); for i in &a.v { let b = iflet MessageItem::DictEntry(ref k, ref v) = *i { let s = format!("{{{}{}}}", k.signature(), v.signature());
s.as_bytes() == esig.to_bytes()
} else {
i.signature().as_cstr() == esig
}; if !b { return Err(ArrayError::DifferentElementTypes) }
}
}
Ok(a)
}
fn element_signature(&self) -> &CStr { let z = &self.sig.as_cstr().to_bytes_with_nul()[1..]; unsafe { CStr::from_bytes_with_nul_unchecked(z) }
}
/// Consumes the MessageItemArray in order to allow you to modify the individual items of the array. pubfn into_vec(self) -> Vec<MessageItem> { self.v }
}
impl ops::Deref for MessageItemArray { type Target = [MessageItem]; fn deref(&self) -> &Self::Target { &yle='color:red'>self.v }
}
/// MessageItem - used as parameters and return values from /// method calls, or as data added to a signal (old, enum version). /// /// Note that the newer generic design (see `arg` module) is both faster /// and less error prone than MessageItem, and should be your first hand choice /// whenever applicable. #[derive(Debug, PartialEq, PartialOrd, Clone)] pubenum MessageItem { /// A D-Bus array requires all elements to be of the same type. /// All elements must match the Signature.
Array(MessageItemArray), /// A D-Bus struct allows for values of different types. Struct(Vec<MessageItem>), /// A D-Bus variant is a wrapper around another `MessageItem`, which /// can be of any type.
Variant(Box<MessageItem>), /// A D-Bus dictionary entry. These are only allowed inside an array.
DictEntry(Box<MessageItem>, Box<MessageItem>), /// A D-Bus objectpath requires its content to be a valid objectpath, /// so this cannot be any string.
ObjectPath(Path<'static>), /// A D-Bus String is zero terminated, so no \0 s in the String, please. /// (D-Bus strings are also - like Rust strings - required to be valid UTF-8.)
Str(String), /// A D-Bus boolean type.
Bool(bool), /// A D-Bus unsigned 8 bit type.
Byte(u8), /// A D-Bus signed 16 bit type.
Int16(i16), /// A D-Bus signed 32 bit type.
Int32(i32), /// A D-Bus signed 64 bit type.
Int64(i64), /// A D-Bus unsigned 16 bit type.
UInt16(u16), /// A D-Bus unsigned 32 bit type.
UInt32(u32), /// A D-Bus unsigned 64 bit type.
UInt64(u64), /// A D-Bus IEEE-754 double-precision floating point type.
Double(f64), /// D-Bus allows for sending file descriptors, which can be used to /// set up SHM, unix pipes, or other communication channels.
UnixFd(OwnedFd),
}
fn iter_get_basic<T>(i: &mut ffi::DBusMessageIter) -> T { unsafe { letmut c: T = mem::zeroed(); let p = &mut c as *mut _ as *mut c_void;
ffi::dbus_message_iter_get_basic(i, p);
c
}
}
impl MessageItem { /// Get the D-Bus Signature for this MessageItem. /// /// Note: Since dictionary entries have no valid signature, calling this function for a dict entry will cause a panic. pubfn signature(&self) -> Signature<'static> { use arg::Variant; match *self {
MessageItem::Str(_) => <String as Arg>::signature(),
MessageItem::Bool(_) => <bool as Arg>::signature(),
MessageItem::Byte(_) => <u8 as Arg>::signature(),
MessageItem::Int16(_) => <i16 as Arg>::signature(),
MessageItem::Int32(_) => <i32 as Arg>::signature(),
MessageItem::Int64(_) => <i64 as Arg>::signature(),
MessageItem::UInt16(_) => <u16 as Arg>::signature(),
MessageItem::UInt32(_) => <u32 as Arg>::signature(),
MessageItem::UInt64(_) => <u64 as Arg>::signature(),
MessageItem::Double(_) => <f64 as Arg>::signature(),
MessageItem::Array(ref a) => a.sig.clone(),
MessageItem::Struct(ref s) => Signature::new(format!("({})", s.iter().fold(String::new(), |s, i| s + &*i.signature()))).unwrap(),
MessageItem::Variant(_) => <Variant<u8> as Arg>::signature(),
MessageItem::DictEntry(_, _) => { panic!("Dict entries are only valid inside arrays, and therefore has no signature on their own") },
MessageItem::ObjectPath(_) => <Path as Arg>::signature(),
MessageItem::UnixFd(_) => <OwnedFd as Arg>::signature(),
}
}
/// Get the D-Bus ASCII type-code for this MessageItem. #[deprecated(note="superseded by signature")] #[allow(deprecated)] pubfn type_sig(&self) -> super::TypeSig<'static> {
Cow::Owned(format!("{}", self.signature()))
}
/// Get the integer value for this MessageItem's type-code. pubfn array_type(&self) -> i32 { let s = matchself {
&MessageItem::Str(_) => ffi::DBUS_TYPE_STRING,
&MessageItem::Bool(_) => ffi::DBUS_TYPE_BOOLEAN,
&MessageItem::Byte(_) => ffi::DBUS_TYPE_BYTE,
&MessageItem::Int16(_) => ffi::DBUS_TYPE_INT16,
&MessageItem::Int32(_) => ffi::DBUS_TYPE_INT32,
&MessageItem::Int64(_) => ffi::DBUS_TYPE_INT64,
&MessageItem::UInt16(_) => ffi::DBUS_TYPE_UINT16,
&MessageItem::UInt32(_) => ffi::DBUS_TYPE_UINT32,
&MessageItem::UInt64(_) => ffi::DBUS_TYPE_UINT64,
&MessageItem::Double(_) => ffi::DBUS_TYPE_DOUBLE,
&MessageItem::Array(_) => ffi::DBUS_TYPE_ARRAY,
&MessageItem::Struct(_) => ffi::DBUS_TYPE_STRUCT,
&MessageItem::Variant(_) => ffi::DBUS_TYPE_VARIANT,
&MessageItem::DictEntry(_,_) => ffi::DBUS_TYPE_DICT_ENTRY,
&MessageItem::ObjectPath(_) => ffi::DBUS_TYPE_OBJECT_PATH,
&MessageItem::UnixFd(_) => ffi::DBUS_TYPE_UNIX_FD,
};
s as i32
}
/// Creates a (String, Variant) dictionary from an iterator with Result passthrough (an Err will abort and return that Err) pubfn from_dict<E, I: Iterator<Item=Result<(String, MessageItem),E>>>(i: I) -> Result<MessageItem, E> { letmut v = Vec::new(); for r in i { let (s, vv) = try!(r);
v.push((s.into(), Box::new(vv).into()).into());
}
Ok(MessageItem::Array(MessageItemArray::new(v, Signature::new("a{sv}").unwrap()).unwrap()))
}
/// Creates an MessageItem::Array from a list of MessageItems. /// /// Note: This requires `v` to be non-empty. See also /// `MessageItem::from(&[T])`, which can handle empty arrays as well. pubfn new_array(v: Vec<MessageItem>) -> Result<MessageItem,ArrayError> { if v.len() == 0 { return Err(ArrayError::EmptyArray);
} let s = MessageItemArray::make_sig(&v[0]);
Ok(MessageItem::Array(MessageItemArray::new(v, s)?))
}
fn new_array2<D, I>(i: I) -> MessageItem where D: Into<MessageItem>, D: Default, I: Iterator<Item=D> { let v: Vec<MessageItem> = i.map(|ii| ii.into()).collect(); let s = { let d; let t = if v.len() == 0 { d = D::default().into(); &d } else { &v[0] };
MessageItemArray::make_sig(t)
};
MessageItem::Array(MessageItemArray::new(v, s).unwrap())
}
fn iter_append_basic<T>(&self, i: &mut ffi::DBusMessageIter, v: T) { let t = self.array_type() as c_int; let p = &v as *const _ as *const c_void; unsafe {
ffi::dbus_message_iter_append_basic(i, t, p);
}
}
fn iter_append(&self, i: &mut ffi::DBusMessageIter) { matchself {
&MessageItem::Str(ref s) => unsafe { let c = to_c_str(s); let p = mem::transmute(&c);
ffi::dbus_message_iter_append_basic(i, ffi::DBUS_TYPE_STRING, p);
},
&MessageItem::Bool(b) => self.iter_append_basic(i, if b { 1u32 } else { 0u32 }),
&MessageItem::Byte(b) => self.iter_append_basic(i, b),
&MessageItem::Int16(b) => self.iter_append_basic(i, b),
&MessageItem::Int32(b) => self.iter_append_basic(i, b),
&MessageItem::Int64(b) => self.iter_append_basic(i, b),
&MessageItem::UInt16(b) => self.iter_append_basic(i, b),
&MessageItem::UInt32(b) => self.iter_append_basic(i, b),
&MessageItem::UInt64(b) => self.iter_append_basic(i, b),
&MessageItem::UnixFd(ref b) => self.iter_append_basic(i, b.as_raw_fd()),
&MessageItem::Double(b) => self.iter_append_basic(i, b),
&MessageItem::Array(ref a) => iter_append_array(i, &a.v, a.element_signature()),
&MessageItem::Struct(ref v) => iter_append_struct(i, &**v),
&MessageItem::Variant(ref b) => iter_append_variant(i, &**b),
&MessageItem::DictEntry(ref k, ref v) => iter_append_dict(i, &**k, &**v),
&MessageItem::ObjectPath(ref s) => unsafe { let c: *const libc::c_char = s.as_ref().as_ptr(); let p = mem::transmute(&c);
ffi::dbus_message_iter_append_basic(i, ffi::DBUS_TYPE_OBJECT_PATH, p);
}
}
}
fn copy_to_iter(i: &mut ffi::DBusMessageIter, v: &[MessageItem]) { for item in v.iter() {
item.iter_append(i);
}
}
/// Conveniently get the inner value of a `MessageItem` /// /// # Example /// ``` /// use dbus::MessageItem; /// let m: MessageItem = 5i64.into(); /// let s: i64 = m.inner().unwrap(); /// assert_eq!(s, 5i64); /// ``` pubfn inner<'a, T: FromMessageItem<'a>>(&'a self) -> Result<T, ()> {
T::from(self)
}
}
// For use by the msgarg module pubfn append_messageitem(i: &mut ffi::DBusMessageIter, m: &MessageItem) {
m.iter_append(i)
}
// For use by the msgarg module pubfn get_messageitem(i: &mut ffi::DBusMessageIter) -> Option<MessageItem> {
MessageItem::from_iter_single(i)
}
/// Helper trait for `MessageItem::inner()` pubtrait FromMessageItem<'a> :Sized { /// Allows converting from a MessageItem into the type it contains. fn from(i: &'a MessageItem) -> Result<Self, ()>;
}
impl<'a> FromMessageItem<'a> for &'a str { fn from(i: &'a MessageItem) -> Result<&'a str,()> { match i {
&MessageItem::Str(ref b) => Ok(&b),
&MessageItem::ObjectPath(ref b) => Ok(&b),
_ => Err(()),
}
}
}
impl<'a> FromMessageItem<'a> for &'a String { fn from(i: &'a MessageItem) -> Result<&'a String,()> { iflet &MessageItem::Str( style='color:red'>ref b) = i { Ok(&b) } else { Err(()) } }
}
impl<'a> FromMessageItem<'a> for &'a Path<'static> { fn from(i: &'a MessageItem) -> Result<&'a Path<'static>,()> { if let &MessageItem::ObjectPath(ref b) = i { Ok(&b) } else { Err(()) } }
}
impl<'a> FromMessageItem<'a> for &'a MessageItem { fn from(i: &'a MessageItem) -> Result<&'a MessageItem,()> { iflet &MessageItem::Variant(ref b) = i { Ok(&**b) } else { Err(()) } }
}
impl<'a> FromMessageItem<'a> for &'a Vec<MessageItem> { fn from(i: &'a MessageItem) -> Result<&'a Vec<MessageItem>,()> { match i {
&MessageItem::Array(ref b) => Ok(&b.v),
&MessageItem::Struct(ref b) => Ok(&b),
_ => Err(()),
}
}
}
/// A D-Bus message. A message contains some headers (e g sender and destination address) /// and a list of MessageItems. pubstruct Message {
msg: *mut ffi::DBusMessage,
}
unsafeimpl Send for Message {}
impl Message { /// Creates a new method call message. pubfn new_method_call<'d, 'p, 'i, 'm, D, P, I, M>(destination: D, path: P, iface: I, method: M) -> Result<Message, String> where D: Into<BusName<'d>>, P: Into<Path<'p>>, I: Into<Interface<'i>>, M: Into<Member<'m>> {
init_dbus(); let (d, p, i, m) = (destination.into(), path.into(), iface.into(), method.into()); let ptr = unsafe {
ffi::dbus_message_new_method_call(d.as_ref().as_ptr(), p.as_ref().as_ptr(), i.as_ref().as_ptr(), m.as_ref().as_ptr())
}; if ptr == ptr::null_mut() { Err("D-Bus error: dbus_message_new_method_call failed".into()) } else { Ok(Message { msg: ptr}) }
}
/// Creates a new signal message. pubfn new_signal<P, I, M>(path: P, iface: I, name: M) -> Result<Message, String> where P: Into<Vec<u8>>, I: Into<Vec<u8>>, M: Into<Vec<u8>> {
init_dbus();
let p = try!(Path::new(path)); let i = try!(Interface::new(iface)); let m = try!(Member::new(name));
/// Creates a new signal message. pubfn signal(path: &Path, iface: &Interface, name: &Member) -> Message {
init_dbus(); let ptr = unsafe {
ffi::dbus_message_new_signal(path.as_ref().as_ptr(), iface.as_ref().as_ptr(), name.as_ref().as_ptr())
}; if ptr == ptr::null_mut() { panic!("D-Bus error: dbus_message_new_signal failed") }
Message { msg: ptr}
}
/// Creates a method reply for this method call. pubfn new_method_return(m: &Message) -> Option<Message> { let ptr = unsafe { ffi::dbus_message_new_method_return(m.msg) }; if ptr == ptr::null_mut() { None } else { Some(Message { msg: ptr} ) }
}
/// Creates a method return (reply) for this method call. pubfn method_return(&self) -> Message { let ptr = unsafe { ffi::dbus_message_new_method_return(self.msg) }; if ptr == ptr::null_mut() { panic!("D-Bus error: dbus_message_new_method_return failed") }
Message {msg: ptr}
}
/// The old way to create a new error reply pubfn new_error(m: &Message, error_name: &str, error_message: &str) -> Option<Message> { let (en, em) = (to_c_str(error_name), to_c_str(error_message)); let ptr = unsafe { ffi::dbus_message_new_error(m.msg, en.as_ptr(), em.as_ptr()) }; if ptr == ptr::null_mut() { None } else { Some(Message { msg: ptr} ) }
}
/// Creates a new error reply pubfn error(&self, error_name: &ErrorName, error_message: &CStr) -> Message { let ptr = unsafe { ffi::dbus_message_new_error(self.msg, error_name.as_ref().as_ptr(), error_message.as_ptr()) }; if ptr == ptr::null_mut() { panic!("D-Bus error: dbus_message_new_error failed") }
Message { msg: ptr}
}
/// Get the MessageItems that make up the message. /// /// Note: use `iter_init` or `get1`/`get2`/etc instead for faster access to the arguments. /// This method is provided for backwards compatibility. pubfn get_items(&self) -> Vec<MessageItem> { letmut i = new_dbus_message_iter(); matchunsafe { ffi::dbus_message_iter_init(self.msg, &mut i) } { 0 => Vec::new(),
_ => MessageItem::from_iter(&mut i)
}
}
/// Get the D-Bus serial of a message, if one was specified. pubfn get_serial(&self) -> u32 { unsafe { ffi::dbus_message_get_serial(self.msg) }
}
/// Get the serial of the message this message is a reply to, if present. pubfn get_reply_serial(&self) -> Option<u32> { let s = unsafe { ffi::dbus_message_get_reply_serial(self.msg) }; if s == 0 { None } else { Some(s) }
}
/// Returns true if the message does not expect a reply. pubfn get_no_reply(&self) -> bool { unsafe { ffi::dbus_message_get_no_reply(self.msg) != 0 } }
/// Set whether or not the message expects a reply. /// /// Set to true if you send a method call and do not want a reply. pubfn set_no_reply(&self, v: bool) { unsafe { ffi::dbus_message_set_no_reply(self.msg, if v { 1 } else { 0 }) }
}
/// Returns true if the message can cause a service to be auto-started. pubfn get_auto_start(&self) -> bool { unsafe { ffi::dbus_message_get_auto_start(self.msg) != 0 } }
/// Sets whether or not the message can cause a service to be auto-started. /// /// Defaults to true. pubfn set_auto_start(&self, v: bool) { unsafe { ffi::dbus_message_set_auto_start(self.msg, if v { 1 } else { 0 }) }
}
/// Add one or more MessageItems to this Message. /// /// Note: using `append1`, `append2` or `append3` might be faster, especially for large arrays. /// This method is provided for backwards compatibility. pubfn append_items(&mutself, v: &[MessageItem]) { letmut i = new_dbus_message_iter(); unsafe { ffi::dbus_message_iter_init_append(self.msg, &mut i) };
MessageItem::copy_to_iter(&mut i, v);
}
/// Appends one MessageItem to a message. /// Use in builder style: e g `m.method_return().append(7i32)` /// /// Note: using `append1`, `append2` or `append3` might be faster, especially for large arrays. /// This method is provided for backwards compatibility. pubfn append<I: Into<MessageItem>>(self, v: I) -> Self { letmut i = new_dbus_message_iter(); unsafe { ffi::dbus_message_iter_init_append(self.msg, &mut i) };
MessageItem::copy_to_iter(&mut i, &[v.into()]); self
}
/// Appends one argument to this message. /// Use in builder style: e g `m.method_return().append1(7i32)` pubfn append1<A: Append>(mutself, a: A) -> Self {
{ letmut m = IterAppend::new(&mutself);
m.append(a);
} self
}
/// Appends two arguments to this message. /// Use in builder style: e g `m.method_return().append2(7i32, 6u8)` pubfn append2<A1: Append, A2: Append>(mutself, a1: A1, a2: A2) -> Self {
{ letmut m = IterAppend::new(&mutself);
m.append(a1); m.append(a2);
} self
}
/// Appends three arguments to this message. /// Use in builder style: e g `m.method_return().append3(7i32, 6u8, true)` pubfn append3<A1: Append, A2: Append, A3: Append>(mutself, a1: A1, a2: A2, a3: A3) -> Self {
{ letmut m = IterAppend::new(&mutself);
m.append(a1); m.append(a2); m.append(a3);
} self
}
/// Appends RefArgs to this message. /// Use in builder style: e g `m.method_return().append_ref(&[7i32, 6u8, true])` pubfn append_ref<A: RefArg>(mutself, r: &[A]) -> Self {
{ letmut m = IterAppend::new(&mutself); for rr in r {
rr.append(&mut m);
}
} self
}
/// Gets the first argument from the message, if that argument is of type G1. /// Returns None if there are not enough arguments, or if types don't match. pubfn get1<'a, G1: Get<'a>>(&'a self) -> Option<G1> { letmut i = Iter::new(&self);
i.get()
}
/// Gets the first two arguments from the message, if those arguments are of type G1 and G2. /// Returns None if there are not enough arguments, or if types don't match. pubfn get2<'a, G1: Get<'a>, G2: Get<'a>>(&'a self) -> (Option<G1>, Option<G2>) { letmut i = Iter::new(&self); let g1 = i.get(); if !i.next() { return (g1, None); }
(g1, i.get())
}
/// Gets the first three arguments from the message, if those arguments are of type G1, G2 and G3. /// Returns None if there are not enough arguments, or if types don't match. pubfn get3<'a, G1: Get<'a>, G2: Get<'a>, G3: Get<'a>>(&'a self) -> (Option<G1>, Option<G2>, Option<G3>) { letmut i = Iter::new(&self); let g1 = i.get(); if !i.next() { return (g1, None, None) } let g2 = i.get(); if !i.next() { return (g1, g2, None) }
(g1, g2, i.get())
}
/// Gets the first four arguments from the message, if those arguments are of type G1, G2, G3 and G4. /// Returns None if there are not enough arguments, or if types don't match. pubfn get4<'a, G1: Get<'a>, G2: Get<'a>, G3: Get<'a>, G4: Get<'a>>(&'a self) -> (Option<G1>, Option<G2>, Option<G3>, Option<G4>) { letmut i = Iter::new(&self); let g1 = i.get(); if !i.next() { return (g1, None, None, None) } let g2 = i.get(); if !i.next() { return (g1, g2, None, None) } let g3 = i.get(); if !i.next() { return (g1, g2, g3, None) }
(g1, g2, g3, i.get())
}
/// Gets the first five arguments from the message, if those arguments are of type G1, G2, G3 and G4. /// Returns None if there are not enough arguments, or if types don't match. /// Note: If you need more than five arguments, use `iter_init` instead. pubfn get5<'a, G1: Get<'a>, G2: Get<'a>, G3: Get<'a>, G4: Get<'a>, G5: Get<'a>>(&>'a self) -> (Option<G1>, Option<G2>, Option<G3>, Option<G4>, Option<G5>) { letmut i = Iter::new(&self); let g1 = i.get(); if !i.next() { return (g1, None, None, None, None) } let g2 = i.get(); if !i.next() { return (g1, g2, None, None, None) } let g3 = i.get(); if !i.next() { return (g1, g2, g3, None, None) } let g4 = i.get(); if !i.next() { return (g1, g2, g3, g4, None) }
(g1, g2, g3, g4, i.get())
}
/// Gets the first argument from the message, if that argument is of type G1. /// /// Returns a TypeMismatchError if there are not enough arguments, or if types don't match. pubfn read1<'a, G1: Arg + Get<'a>>(&'a self) -> Result<G1, TypeMismatchError> { letmut i = Iter::new(&self);
i.read()
}
/// Gets the first two arguments from the message, if those arguments are of type G1 and G2. /// /// Returns a TypeMismatchError if there are not enough arguments, or if types don't match. pubfn read2<'a, G1: Arg + Get<'a>, G2: Arg + Get<'a>>(&'a self) -> Result<(G1, G2), TypeMismatchError> { letmut i = Iter::new(&self);
Ok((try!(i.read()), try!(i.read())))
}
/// Gets the first three arguments from the message, if those arguments are of type G1, G2 and G3. /// /// Returns a TypeMismatchError if there are not enough arguments, or if types don't match. pubfn read3<'a, G1: Arg + Get<'a>, G2: Arg + Get<'a>, G3: Arg + Get<'a>>(&'a self) ->
Result<(G1, G2, G3), TypeMismatchError> { letmut i = Iter::new(&self);
Ok((try!(i.read()), try!(i.read()), try!(i.read())))
}
/// Gets the first four arguments from the message, if those arguments are of type G1, G2, G3 and G4. /// /// Returns a TypeMismatchError if there are not enough arguments, or if types don't match. pubfn read4<'a, G1: Arg + Get<'a>, G2: Arg + Get<'a>, G3: Arg + Get<'a>, G4: Arg + Get<'a>>(&'a self) ->
Result<(G1, G2, G3, G4), TypeMismatchError> { letmut i = Iter::new(&self);
Ok((try!(i.read()), try!(i.read()), try!(i.read()), try!(i.read())))
}
/// Gets the first five arguments from the message, if those arguments are of type G1, G2, G3, G4 and G5. /// /// Returns a TypeMismatchError if there are not enough arguments, or if types don't match. /// Note: If you need more than five arguments, use `iter_init` instead. pubfn read5<'a, G1: Arg + Get<'a>, G2: Arg + Get<'a>, G3: Arg + Get<'a>, G4: Arg + Get<'a>, G5: Arg + Get<'a>>(&an style='color:blue'>'a self) ->
Result<(G1, G2, G3, G4, G5), TypeMismatchError> { letmut i = Iter::new(&self);
Ok((try!(i.read()), try!(i.read()), try!(i.read()), try!(i.read()), try!(i.read())))
}
/// Returns a struct for retreiving the arguments from a message. Supersedes get_items(). pubfn iter_init<'a>(&'a self) -> Iter<'a> { Iter::new(&self) }
/// Gets the MessageType of the Message. pubfn msg_type(&self) -> MessageType { unsafe { mem::transmute(ffi::dbus_message_get_type(self.msg)) }
}
/// Gets the name of the connection that originated this message. pubfn sender<'a>(&'a self) -> Option<BusName<'a>> { self.msg_internal_str(unsafe { ffi::dbus_message_get_sender(self.msg) })
.map(|s| unsafe { BusName::from_slice_unchecked(s) })
}
/// Returns a tuple of (Message type, Path, Interface, Member) of the current message. pubfn headers(&self) -> (MessageType, Option<String>, Option<String>, Option<String>) { let p = unsafe { ffi::dbus_message_get_path(self.msg) }; let i = unsafe { ffi::dbus_message_get_interface(self.msg) }; let m = unsafe { ffi::dbus_message_get_member(self.msg) };
(self.msg_type(),
c_str_to_slice(&p).map(|s| s.to_string()),
c_str_to_slice(&i).map(|s| s.to_string()),
c_str_to_slice(&m).map(|s| s.to_string()))
}
/// Gets the object path this Message is being sent to. pubfn path<'a>(&'a self) -> Option<Path<'a>> { self.msg_internal_str(unsafe { ffi::dbus_message_get_path(self.msg) })
.map(|s| unsafe { Path::from_slice_unchecked(s) })
}
/// Gets the destination this Message is being sent to. pubfn destination<'a>(&'a self) -> Option<BusName<'a>> { self.msg_internal_str(unsafe { ffi::dbus_message_get_destination(self.msg) })
.map(|s| unsafe { BusName::from_slice_unchecked(s) })
}
/// Sets the destination of this Message /// /// If dest is none, that means broadcast to all relevant destinations. pubfn set_destination(&mutself, dest: Option<BusName>) { let c_dest = dest.as_ref().map(|d| d.as_cstr().as_ptr()).unwrap_or(ptr::null());
assert!(unsafe { ffi::dbus_message_set_destination(self.msg, c_dest) } != 0);
}
/// Gets the interface this Message is being sent to. pubfn interface<'a>(&'a self) -> Option<Interface<'a>> { self.msg_internal_str(unsafe { ffi::dbus_message_get_interface(self.msg) })
.map(|s| unsafe { Interface::from_slice_unchecked(s) })
}
/// Gets the interface member being called. pubfn member<'a>(&'a self) -> Option<Member<'a>> { self.msg_internal_str(unsafe { ffi::dbus_message_get_member(self.msg) })
.map(|s| unsafe { Member::from_slice_unchecked(s) })
}
/// When the remote end returns an error, the message itself is /// correct but its contents is an error. This method will /// transform such an error to a D-Bus Error or otherwise return /// the original message. pubfn as_result(&mutself) -> Result<&mut Message, Error> { self.set_error_from_msg().map(|_| self)
}
/// A convenience struct that wraps connection, destination and path. /// /// Useful if you want to make many method calls to the same destination path. #[derive(Clone, Debug)] pubstruct ConnPath<'a, C> { /// Some way to access the connection, e g a &Connection or Rc<Connection> pub conn: C, /// Destination, i e what D-Bus service you're communicating with pub dest: BusName<'a>, /// Object path on the destination pub path: Path<'a>, /// Timeout in milliseconds for blocking method calls pub timeout: i32,
}
impl<'a, C: ::std::ops::Deref<Target=Connection>> ConnPath<'a, C> { /// Make a D-Bus method call, where you can append arguments inside the closure. pubfn method_call_with_args<F: FnOnce(&mut Message)>(&='color:red'>self, i: &Interface, m: &Member, f: F) -> Result<Message, Error> { letmut msg = Message::method_call(&self.dest, &self.path, i, m);
f(&mut msg); self.conn.send_with_reply_and_block(msg, self.timeout)
}
/// Emit a D-Bus signal, where you can append arguments inside the closure. pubfn signal_with_args<F: FnOnce(&mut Message)>(&self, i: &Interface, m: &Member, f: F) -> Result<u32, Error> { letmut msg = Message::signal(&self.path, i, m);
f(&mut msg); self.conn.send(msg).map_err(|_| Error::new_custom("org.freedesktop.DBus.Error.Failed", "Sending signal failed"))
}
/// Emit a D-Bus signal, where the arguments are in a struct. pubfn emit<S: SignalArgs>(&self, signal: &S) -> Result<u32, Error> { let msg = signal.to_emit_message(&self.path); self.conn.send(msg).map_err(|_| Error::new_custom("org.freedesktop.DBus.Error.Failed", "Sending signal failed"))
}
}
// For purpose of testing the library only. #[cfg(test)] pub (crate) fn message_set_serial(m: &mut Message, s: u32) { unsafe { ffi::dbus_message_set_serial(m.msg, s) };
}
let c = Connection::get_private(BusType::Session).unwrap();
c.register_object_path("/hello").unwrap(); letmut msg = Message::new_method_call(&c.unique_name(), "/hello", "org.freedesktop.DBusObjectManager", "GetManagedObjects").unwrap();
msg.append_items(&[m]); let sending = format!("{:?}", msg.get_items());
println!("Sending {}", sending);
c.send(msg).unwrap();
loop { for n in c.incoming(1000) { if n.msg_type() == MessageType::MethodCall { let receiving = format!("{:?}", n.get_items());
println!("Receiving {}", receiving);
assert_eq!(sending, receiving); return;
} else {
println!("Got {:?}", n);
}
} }
}
#[test] fn issue24() { let c = Connection::get_private(BusType::Session).unwrap(); letmut m = Message::new_method_call("org.test.rust", "/", "org.test.rust", "Test").unwrap();
let a = MessageItem::from("test".to_string()); let b = MessageItem::from("test".to_string()); let foo = MessageItem::Struct(vec!(a, b)); let bar = foo.clone();
let args = [MessageItem::new_array(vec!(foo, bar)).unwrap()];
println!("{:?}", args);
m.append_items(&args);
c.send(m).unwrap();
}
#[test] fn set_valid_destination() { letmut m = Message::new_method_call("org.test.rust", "/", "org.test.rust", "Test").unwrap(); let d = Some(BusName::new(":1.14").unwrap());
m.set_destination(d);
¤ Diese beiden folgenden Angebotsgruppen bietet das Unternehmen0.18Angebot
(Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können 2026-06-18)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.