1use std::any::type_name;
5
6use whence::WhenceExt;
7use xous_ipc::XousValidator;
8
9use crate::{Error, Owned, Server, ServerContext};
10
11pub trait ArchiveHandler<M>
13where
14 M: Archive,
15 Self: Server,
16{
17 fn handle(&mut self, msg: Owned<M>, sender: xous::PID, context: &mut ServerContext<Self>);
18}
19
20pub trait Archive: crate::ArchiveCodec + crate::MessageId + 'static {}
22
23pub fn handle_archive_message<M, S>(
25 handler: &mut S,
26 raw: xous::MessageEnvelope,
27 context: &mut ServerContext<S>,
28) where
29 M: Archive,
30 S: ArchiveHandler<M>,
31 <M as rkyv::Archive>::Archived: for<'a> rkyv::bytecheck::CheckBytes<XousValidator<'a>>,
32{
33 let pid = raw.sender.pid().unwrap();
34 if let Err(e) = try_handle_archive_message(pid, handler, raw, context) {
35 log::warn!("Archive handle error (PID {pid}) for {}: {e}", type_name::<M>());
36 }
37}
38
39fn try_handle_archive_message<M, S>(
40 pid: xous::PID,
41 handler: &mut S,
42 raw: xous::MessageEnvelope,
43 context: &mut ServerContext<S>,
44) -> whence::Result<(), Error>
45where
46 M: Archive,
47 S: ArchiveHandler<M>,
48 <M as rkyv::Archive>::Archived: for<'a> rkyv::bytecheck::CheckBytes<XousValidator<'a>>,
49{
50 let msg = Owned::new_move(raw).whence()?;
51 handler.handle(msg, pid, context);
52 Ok(())
53}
54
55pub fn send_archive<M>(cid: xous::CID, msg: M) -> Result<(), xous::Error>
59where
60 M: Archive,
61{
62 xous_ipc::Buffer::into_buf(&msg).map_err(|_| xous::Error::InternalError)?.send(cid, M::ID as u32)?;
63 Ok(())
64}
65
66pub fn send_archive_nowait<M>(cid: xous::CID, msg: M) -> Result<(), xous::Error>
70where
71 M: Archive,
72{
73 let buf = xous_ipc::Buffer::into_buf(&msg).map_err(|_| xous::Error::InternalError)?;
74 buf.send_nowait(cid, M::ID as u32)?;
75 Ok(())
76}