atspi 0.10.1

Pure-Rust, zbus-based AT-SPI2 protocol implementation.
Documentation
//! ## Signified signal types
//!
//! The generic `AtspiEvent` has a specific meaning depending on its origin.
//! This module offers the signified types and their conversions from a generic `AtpiEvent`.
//!
//! The `TrySignify` macro implements a `TryFrom<Event>` on a per-name and member basis
//!

use crate::events::{AtspiEvent, GenericEvent};
use std::collections::HashMap;
use std::sync::Arc;
use zbus::{names::MemberName, zvariant, Message};
use zbus_names::{self, InterfaceName};
use zvariant::OwnedValue;

/// All Atspi / Qspi event types encapsulate `AtspiEvent`.
/// This trait allows access to the underlying item.
pub trait Signified {
	type Inner;

	fn inner(&self) -> &AtspiEvent;
	fn properties(&self) -> &HashMap<String, OwnedValue>;
	fn kind(&self) -> &str;
}

/// Shared functionality of Events, through its `Message` header
impl<T> GenericEvent for T
where
	T: Signified,
{
	/// Serialized bus message.
	#[must_use]
	fn message(&self) -> &Arc<Message> {
		&self.inner().message
	}

	// For now this returns the full interface name because the lifetimes in [`zbus_names`][zbus::names] are
	// wrong such that the `&str` you can get from a
	// [`zbus_names::InterfaceName`][zbus::names::InterfaceName] is tied to the lifetime of that
	// name, not to the lifetime of the message as it should be. In future, this will return only
	// the last component of the interface name (I.E. "Object" from
	// "org.a11y.atspi.Event.Object").

	/// The emitting interface.
	#[must_use]
	fn interface(&self) -> Option<InterfaceName<'_>> {
		self.inner().message.interface()
	}

	/// The interface member that dispatched this event / signal.
	///
	/// Members of the interface are either signals, methods or properties.
	/// eg. `PropertyChanged` or `TextChanged`
	#[must_use]
	fn member(&self) -> Option<MemberName<'_>> {
		self.inner().message.member()
	}

	/// The object path to the object where the signal is emitted from.
	#[must_use]
	fn path(&self) -> std::option::Option<zbus::zvariant::ObjectPath<'_>> {
		self.inner().message.path()
	}

	/// Identifies the `sender` of the `Event`.
	/// # Errors
	/// - when deserializeing the header failed, or
	/// * When `zbus::get_field!` finds that 'sender' is an invalid field.
	fn sender(&self) -> Result<Option<zbus::names::UniqueName>, crate::AtspiError> {
		Ok(self.inner().message.header()?.sender()?.cloned())
	}
}