#[cfg(feature = "zbus")]
use crate::AtspiError;
use crate::ObjectRef;
#[cfg(feature = "zbus")]
use serde::{Deserialize, Serialize};
#[cfg(feature = "zbus")]
use zbus::message::{Body as DbusBody, Header};
use zbus_names::UniqueName;
use zvariant::ObjectPath;
#[cfg(feature = "zbus")]
use zvariant::Type;
pub trait EventTypeProperties {
fn member(&self) -> &'static str;
fn interface(&self) -> &'static str;
fn match_rule(&self) -> &'static str;
fn registry_string(&self) -> &'static str;
}
pub trait EventProperties {
fn sender(&self) -> UniqueName<'_>;
fn path(&self) -> ObjectPath<'_>;
fn object_ref(&self) -> ObjectRef {
ObjectRef { name: self.sender().into(), path: self.path().into() }
}
}
assert_obj_safe!(EventTypeProperties);
assert_obj_safe!(EventProperties);
#[cfg(all(feature = "zbus", feature = "wrappers"))]
pub(crate) trait EventWrapperMessageConversion {
fn try_from_message_interface_checked(
msg: &zbus::Message,
hdr: &Header,
) -> Result<Self, AtspiError>
where
Self: Sized;
}
#[cfg(all(feature = "zbus", feature = "wrappers"))]
pub(crate) trait TryFromMessage {
fn try_from_message(msg: &zbus::Message) -> Result<Self, AtspiError>
where
Self: Sized;
}
pub trait DBusMember {
const DBUS_MEMBER: &'static str;
}
pub trait DBusInterface {
const DBUS_INTERFACE: &'static str;
}
pub trait DBusMatchRule {
const MATCH_RULE_STRING: &'static str;
}
pub trait RegistryEventString {
const REGISTRY_EVENT_STRING: &'static str;
}
pub trait DBusProperties: DBusMember + DBusInterface + DBusMatchRule + RegistryEventString {}
#[cfg(feature = "zbus")]
pub trait MessageConversionExt<'a, B>: 'a + MessageConversion<'a, Body<'a> = B>
where
B: Type + Serialize + Deserialize<'a>,
{
fn try_from_message(msg: &'a zbus::Message, hdr: &Header) -> Result<Self, AtspiError>
where
Self: Sized + 'a;
fn validate_interface(header: &Header) -> Result<(), AtspiError> {
let interface = header.interface().ok_or(AtspiError::MissingInterface)?;
if interface != Self::DBUS_INTERFACE {
return Err(AtspiError::InterfaceMatch(format!(
"The interface {} does not match the signal's interface: {}",
interface,
Self::DBUS_INTERFACE,
)));
}
Ok(())
}
fn validate_member(hdr: &Header) -> Result<(), AtspiError> {
let member = hdr.member().ok_or(AtspiError::MissingMember)?;
if member != Self::DBUS_MEMBER {
return Err(AtspiError::MemberMatch(format!(
"The member {} does not match the signal's member: {}",
member,
Self::DBUS_MEMBER,
)));
}
Ok(())
}
fn validate_body(msg: &zbus::Message) -> Result<(), AtspiError> {
let body = msg.body();
let body_signature = body.signature();
let expected_signature = B::SIGNATURE;
if body_signature != expected_signature {
return Err(AtspiError::SignatureMatch(format!(
"The message signature {} does not match the signal's body signature: {}",
body_signature,
&expected_signature.to_string(),
)));
}
Ok(())
}
}
#[cfg(feature = "zbus")]
pub trait MessageConversion<'a>: DBusProperties {
type Body<'msg>: Type + Deserialize<'msg> + Serialize
where
Self: 'msg;
fn from_message_unchecked(msg: &zbus::Message, header: &Header) -> Result<Self, AtspiError>
where
Self: Sized + 'a;
fn from_message_unchecked_parts(obj_ref: ObjectRef, body: DbusBody) -> Result<Self, AtspiError>
where
Self: Sized;
fn body(&self) -> Self::Body<'_>;
}