Files
arrayvec
async_attributes
async_channel
async_executor
async_global_executor
async_io
async_lock
async_mutex
async_process
async_rustbus
async_std
collections
fs
future
io
net
option
os
path
pin
result
rt
stream
string
sync
task
unit
vec
async_task
atomic_waker
bitflags
blocking
cache_padded
cfg_if
concurrent_queue
crossbeam_utils
ctor
derive_utils
event_listener
fastrand
find_crate
futures
futures_channel
futures_core
futures_enum
futures_executor
futures_io
futures_lite
futures_macro
futures_sink
futures_task
futures_util
async_await
future
io
lock
sink
stream
task
kv_log_macro
lazy_static
libc
log
memchr
nix
num_cpus
once_cell
parking
pin_project_lite
pin_utils
polling
proc_macro2
proc_macro_hack
proc_macro_nested
quote
rustable
rustbus
rustbus_derive
serde
signal_hook
signal_hook_registry
slab
socket2
syn
toml
unicode_xid
value_bag
void
waker_fn
xml
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
//! # Rustbus
//! Rustbus is a dbus library that allows for clients to perform method_calls on services on the bus or to implement your own service that listens on the bus.
//!
//! ## Quickstart
//! ```rust,no_run
//! use rustbus::{connection::Timeout, get_session_bus_path, DuplexConn, MessageBuilder, connection::ll_conn::force_finish_on_error};
//! fn main() -> Result<(), rustbus::connection::Error> {
//!     /// To get a connection going you need to connect to a bus. You will likely use either the session or the system bus.
//!     let session_path = get_session_bus_path()?;
//!     let mut con = DuplexConn::connect_to_bus(session_path, true)?;
//!     // Dont forget to send the obligatory hello message. send_hello wraps the call and parses the response for convenience.
//!     let unique_name = con.send_hello(Timeout::Infinite)?;
//!
//!     // Next you will probably want to create a new message to send out to the world
//!     let mut sig = MessageBuilder::new()
//!         .signal(
//!             "io.killing.spark",
//!             "TestSignal",
//!             "/io/killing/spark",
//!         )
//!         .build();
//!     
//!     // To put parameters into that message you use the sig.body.push_param functions. These accept anything that can be marshalled into a dbus parameter
//!     // You can derive or manually implement that trait for your own types if you need that.
//!     sig.body.push_param("My cool new Signal!").unwrap();
//!     
//!     // Now send you signal to all that want to hear it!
//!     con.send.send_message(&sig)?.write_all().map_err(force_finish_on_error)?;
//!     
//!     // To receive messages sent to you you can call the various functions on the RecvConn. The simplest is this:
//!     let message = con.recv.get_next_message(Timeout::Infinite)?;  
//!     
//!     // Now you can inspect the message.dynheader for all the metadata on the message
//!     println!("The messages dynamic header: {:?}", message.dynheader);
//!
//!     // After inspecting that dynheader you should know which content the message should contain
//!     let cool_string = message.body.parser().get::<&str>().unwrap();
//!     println!("Received a cool string: {}", cool_string);
//!     Ok(())
//! }
//! ```
//!
//! ## Other connection Types
//! There are some more connection types in the connection module. These are convenience wrappes around the concepts presented in the quickstart.
//! * RpcConn is meant for clients calling methods on services on the bus
//! * DispatchConn is meant for services that need to dispatch calls to many handlers.
//!
//! Since different usecases have different constraints you might need to write your own wrapper around the low level conn. This should not be too hard
//! if you copy the existing ones and modify them to your needs. If you have an issue that would be helpful for others I would of course consider adding
//! it to this libary.
//!
//! ## Params and Marshal and Unmarshal
//! This lib started out as an attempt to understand how dbus worked. Thus I modeled the types a closely as possible with enums, which is still in the params module.
//! This is kept around for weird weird edge-cases where that might be necessary but they should not generally be used.
//!
//! Instead you should be using the Marshal and Unmarshal traits which are implemented for most common types you will need. The idea is to map rust types
//! as closely as possible to dbus types. The trivial types like String and u64 etc are dealt with easily. For tuple-structs there are impls up to a
//! certain size. After that you'd need to copy the impl from this lib and extend it accordingly. This might be dealt with in the future if variadic generics get
//! added to rust.
//!
//! For structs there is a derive proc-macro that derives the necessary trait impls for you. Look into rustbus_derive if this is of need for you.
//!
//! For Variants there is a macro dbus_variant_sig! and dbus_variant_var! which will generate an enum and the Marshal and Unmarshal impls for you. These might get
//! replaced with a proc-macro derive like it exists already for structs.
//!
//! The doc for the traits gives more specifics on how to implement them for your own types if necessary.
//!
//! There is an exmaple for all of this in `examples/user_defined_types.rs`.
//! And for the deriving for structs there is an example in `examples/deriving.rs`
//!
//! ## Filedescriptors
//! Dbus can send filedescriptors around for you. Rustbus supports this. There is a special wrapper type in the wire module. This type tries to sensibly deal with
//! the pitfalls of sending and receiving filedescriptors in a sensible way. If you see any issues with the API or have wishes for extensions to the API please
//! open an issue.
//!
//! ## Byteorders
//! Dbus supports both big and little endian and so does rustbus. You can specify how a message should be marshalled when you create the MessageBuilder. Messages
//! can be received in any byteorder and will be transparently unmarshalled into the byteorder you CPU uses. Note that unmarshalling from/to the native byteorder will
//! be faster. The default byteorder is little endian.

pub mod auth;
pub mod connection;
pub mod message_builder;
pub mod params;
pub mod peer;
pub mod signature;
pub mod standard_messages;
pub mod wire;

// reexport derive macros
pub use rustbus_derive::*;

// TODO create a rustbus::prelude

// needed to make own filters in RpcConn
pub use message_builder::MessageType;

// needed to create a connection
pub use connection::dispatch_conn::DispatchConn;
pub use connection::ll_conn::DuplexConn;
pub use connection::ll_conn::RecvConn;
pub use connection::ll_conn::SendConn;
pub use connection::rpc_conn::RpcConn;
pub use connection::{get_session_bus_path, get_system_bus_path};

// needed to make new messages
pub use message_builder::{CallBuilder, MessageBuilder, SignalBuilder};
pub use wire::marshal::traits::Marshal;
pub use wire::marshal::traits::Signature;
pub use wire::unmarshal::traits::Unmarshal;

#[cfg(test)]
mod tests;

/// The supported byte orders
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum ByteOrder {
    LittleEndian,
    BigEndian,
}

impl ByteOrder {
    const NATIVE: Self = match cfg!(target_endian = "little") {
        true => ByteOrder::LittleEndian,
        false => ByteOrder::BigEndian,
    };
}

/// The different errors that can occur when dealing with messages
#[derive(Debug, Eq, PartialEq)]
pub enum Error {
    InvalidType,
    EmptyArray,
    EmptyDict,
    StringContainsNullByte,
    Marshal(crate::wire::marshal::Error),
    Unmarshal(crate::wire::unmarshal::Error),
    Validation(crate::params::validation::Error),
}

impl From<crate::params::validation::Error> for Error {
    fn from(e: crate::params::validation::Error) -> Self {
        Error::Validation(e)
    }
}
impl From<crate::wire::unmarshal::Error> for Error {
    fn from(e: crate::wire::unmarshal::Error) -> Self {
        Error::Unmarshal(e)
    }
}
impl From<crate::signature::Error> for Error {
    fn from(e: crate::signature::Error) -> Self {
        Error::Validation(crate::params::validation::Error::InvalidSignature(e))
    }
}