#[cfg(feature = "zbus")]
use crate::AtspiError;
use crate::ObjectRef;
#[cfg(feature = "zbus")]
use serde::{Deserialize, Serialize};
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() }
}
}
pub trait BusProperties {
const DBUS_MEMBER: &'static str;
const DBUS_INTERFACE: &'static str;
const MATCH_RULE_STRING: &'static str;
const REGISTRY_EVENT_STRING: &'static str;
}
pub trait HasInterfaceName {
const DBUS_INTERFACE: &'static str;
}
pub trait HasMatchRule {
const MATCH_RULE_STRING: &'static str;
}
pub trait HasRegistryEventString {
const REGISTRY_EVENT_STRING: &'static str;
}
#[cfg(feature = "zbus")]
pub(crate) trait EventWrapperMessageConversion {
fn try_from_message_interface_checked(msg: &zbus::Message) -> Result<Self, AtspiError>
where
Self: Sized;
}
#[cfg(feature = "zbus")]
pub(crate) trait TryFromMessage {
fn try_from_message(msg: &zbus::Message) -> Result<Self, AtspiError>
where
Self: Sized;
}
#[cfg(feature = "zbus")]
pub trait MessageConversionExt<B>: MessageConversion<Body = B>
where
B: Type + Serialize + for<'a> Deserialize<'a>,
{
fn try_from_message(msg: &zbus::Message) -> Result<Self, AtspiError>
where
Self: Sized;
fn validate_interface(msg: &zbus::Message) -> Result<(), AtspiError> {
let header = msg.header();
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(msg: &zbus::Message) -> Result<(), AtspiError> {
let header = msg.header();
let member = header.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();
if body_signature != Self::Body::SIGNATURE {
return Err(AtspiError::SignatureMatch(format!(
"The message signature {} does not match the signal's body signature: {:?}",
body_signature,
Self::Body::SIGNATURE
)));
}
Ok(())
}
}
#[cfg(feature = "zbus")]
pub trait MessageConversion: BusProperties {
type Body: Type + Serialize + for<'a> Deserialize<'a>;
fn from_message_unchecked(msg: &zbus::Message) -> Result<Self, AtspiError>
where
Self: Sized;
fn from_message_unchecked_parts(
obj_ref: ObjectRef,
body: Self::Body,
) -> Result<Self, AtspiError>
where
Self: Sized;
fn body(&self) -> Self::Body;
}