macro_rules! atom_manager { { $(#[$struct_meta:meta])* $vis:vis $struct_name:ident: $(#[$cookie_meta:meta])* $cookie_name:ident { $($field_name:ident$(: $atom_value:expr)?,)* } } => { ... }; }
Expand description
A helper macro for managing atoms
In X11, one often has to work with many different atoms that are already known at compile time. This macro can simplify managing such a list of atoms.
The following macro invocation:
atom_manager! {
/// A collection of Atoms.
pub AtomCollection:
/// A handle to a response from the X11 server.
AtomCollectionCookie {
_NET_WM_NAME,
_NET_WM_ICON,
ATOM_WITH_SPACES: b"ATOM WITH SPACES",
WHATEVER,
}
}
…expands to this:
#[allow(non_snake_case)]
#[derive(Debug, Clone, Copy)]
/// A collection of Atoms.
pub struct AtomCollection {
pub _NET_WM_NAME: Atom,
pub _NET_WM_ICON: Atom,
pub ATOM_WITH_SPACES: Atom,
pub WHATEVER: Atom,
}
#[allow(non_snake_case)]
#[derive(Debug)]
/// A handle to a response from the X11 server.
struct AtomCollectionCookie<'c, C: ConnectionExt> {
// please treat the actual members as private
}
impl AtomCollection {
pub fn new<C: ConnectionExt>(
conn: &C,
) -> Result<AtomCollectionCookie<'_, C>, ConnectionError> {
// This is just an example for readability; the actual code is more efficient.
Ok(AtomCollectionCookie {
phantom: std::marker::PhantomData,
_NET_WM_NAME: conn.intern_atom(false, b"_NET_WM_NAME")?,
_NET_WM_ICON: conn.intern_atom(false, b"_NET_WM_ICON")?,
ATOM_WITH_SPACES: conn.intern_atom(false, b"ATOM WITH SPACES")?,
WHATEVER: conn.intern_atom(false, b"WHATEVER")?,
})
}
}
impl<'c, C> AtomCollectionCookie<'c, C>
where
C: ConnectionExt,
{
pub fn reply(self) -> Result<AtomCollection, ReplyError> {
// This is just an example for readability; the actual code is different.
Ok(AtomCollection {
_NET_WM_NAME: self._NET_WM_NAME.reply()?.atom,
_NET_WM_ICON: self._NET_WM_ICON.reply()?.atom,
ATOM_WITH_SPACES: self.ATOM_WITH_SPACES.reply()?.atom,
WHATEVER: self.WHATEVER.reply()?.atom,
})
}
}