mod dispatch_result;
pub use dispatch_result::*;
mod interface_ref;
pub use interface_ref::*;
mod interface_deref;
pub use interface_deref::*;
use std::{
any::{Any, TypeId},
collections::HashMap,
fmt::{self, Write},
sync::Arc,
};
use async_trait::async_trait;
use zbus_names::{InterfaceName, MemberName};
use zvariant::{OwnedValue, Value};
use crate::{
Connection, ObjectServer,
async_lock::RwLock,
fdo,
message::{self, Header, Message},
object_server::SignalEmitter,
};
#[async_trait]
pub trait Interface: Any + Send + Sync {
fn name() -> InterfaceName<'static>
where
Self: Sized;
fn spawn_tasks_for_methods(&self) -> bool {
true
}
async fn get(
&self,
property_name: &str,
server: &ObjectServer,
connection: &Connection,
header: Option<&message::Header<'_>>,
emitter: &SignalEmitter<'_>,
) -> Option<fdo::Result<OwnedValue>>;
async fn get_all(
&self,
object_server: &ObjectServer,
connection: &Connection,
header: Option<&message::Header<'_>>,
emitter: &SignalEmitter<'_>,
) -> fdo::Result<HashMap<String, OwnedValue>>;
fn set<'call>(
&'call self,
property_name: &'call str,
value: &'call Value<'_>,
object_server: &'call ObjectServer,
connection: &'call Connection,
header: Option<&'call message::Header<'_>>,
emitter: &'call SignalEmitter<'_>,
) -> DispatchResult2<'call> {
let _ = (
property_name,
value,
object_server,
connection,
header,
emitter,
);
DispatchResult2::RequiresMut
}
async fn set_mut(
&mut self,
property_name: &str,
value: &Value<'_>,
object_server: &ObjectServer,
connection: &Connection,
header: Option<&Header<'_>>,
emitter: &SignalEmitter<'_>,
) -> Option<fdo::Result<()>>;
fn call<'call>(
&'call self,
server: &'call ObjectServer,
connection: &'call Connection,
msg: &'call Message,
name: MemberName<'call>,
) -> DispatchResult2<'call>;
fn call_mut<'call>(
&'call mut self,
server: &'call ObjectServer,
connection: &'call Connection,
msg: &'call Message,
name: MemberName<'call>,
) -> DispatchResult2<'call>;
fn introspect_to_writer(&self, writer: &mut dyn Write, level: usize);
}
#[derive(Clone)]
pub(crate) struct ArcInterface {
pub instance: Arc<RwLock<dyn Interface>>,
pub spawn_tasks_for_methods: bool,
}
impl ArcInterface {
pub fn new<I>(iface: I) -> Self
where
I: Interface,
{
let spawn_tasks_for_methods = iface.spawn_tasks_for_methods();
Self {
instance: Arc::new(RwLock::new(iface)),
spawn_tasks_for_methods,
}
}
}
impl fmt::Debug for ArcInterface {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Arc<RwLock<dyn Interface>>")
.finish_non_exhaustive()
}
}
impl dyn Interface {
pub(crate) fn downcast_ref<T: Any>(&self) -> Option<&T> {
if <dyn Interface as Any>::type_id(self) == TypeId::of::<T>() {
Some(unsafe { &*(self as *const dyn Interface as *const T) })
} else {
None
}
}
pub(crate) fn downcast_mut<T: Any>(&mut self) -> Option<&mut T> {
if <dyn Interface as Any>::type_id(self) == TypeId::of::<T>() {
Some(unsafe { &mut *(self as *mut dyn Interface as *mut T) })
} else {
None
}
}
}