1pub use archive::*;
4pub use scalar::*;
5
6mod archive;
7mod scalar;
8
9use rkyv::bytecheck::CheckBytes;
10use whence::WhenceExt;
11use xous_ipc::{XousDeserializer, XousValidator};
12
13use crate::{Error, WrongMessageTypeError};
14
15pub trait SubscriptionError
16where
17 Self: crate::ArchiveCodec,
18 <Result<(), Self> as rkyv::Archive>::Archived:
19 rkyv::Deserialize<Result<(), Self>, XousDeserializer> + for<'a> CheckBytes<XousValidator<'a>>,
20{
21}
22
23impl<T> SubscriptionError for T
24where
25 T: crate::ArchiveCodec,
26
27 <Result<(), T> as rkyv::Archive>::Archived:
28 rkyv::Deserialize<Result<(), T>, XousDeserializer> + for<'a> CheckBytes<XousValidator<'a>>,
29{
30}
31
32#[derive(Debug, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
33pub struct EventSubscriptionMessage<T> {
34 pub cid: xous::CID,
35 pub msg_id: xous::MessageId,
36 pub cancel_msg_id: xous::MessageId,
37 pub msg: T,
38}
39
40impl<T> EventSubscriptionMessage<T>
41where
42 T: scalar::ScalarSubscription,
43{
44 #[inline]
45 pub fn send_scalar(self, cid: xous::CID) -> whence::Result<Result<(), T::Error>, Error> {
46 let mut buf = xous_ipc::Buffer::into_buf(&self).whence()?;
47 buf.lend_mut(cid, T::ID as u32).whence()?;
48 buf.to_original::<Result<(), T::Error>>().whence()
49 }
50}
51
52impl<T> EventSubscriptionMessage<T>
53where
54 T: archive::ArchiveSubscription,
55{
56 #[inline]
57 pub fn send_archive(self, cid: xous::CID) -> whence::Result<Result<(), T::Error>, Error> {
58 let mut buf = xous_ipc::Buffer::into_buf(&self).whence()?;
59 buf.lend_mut(cid, T::ID as u32).whence()?;
60 buf.to_original::<Result<(), T::Error>>().whence()
61 }
62}
63
64fn cancellation_message(msg_id: xous::MessageId, cancel_msg_id: xous::MessageId) -> xous::Message {
65 xous::Message::new_scalar(cancel_msg_id, msg_id, cancel_msg_id, 0, 0)
66}
67
68pub fn extract_cancellation_message(
69 msg: &xous::Message,
70) -> Result<(xous::MessageId, xous::MessageId), Error> {
71 match msg {
72 xous::Message::Scalar(scalar) => Ok((scalar.arg1 as usize, scalar.arg2 as usize)),
73 _ => {
74 let err: rkyv::rancor::Error = rkyv::rancor::Source::new(WrongMessageTypeError);
75 Err(err.into())
76 }
77 }
78}
79
80pub use infallible::Infallible;
81
82mod infallible {
83 #[derive(Debug, Clone, Copy)]
86 pub enum Infallible {}
87
88 impl rkyv::Archive for Infallible {
89 type Archived = ArchivedInfallible;
90 type Resolver = ();
91
92 fn resolve(&self, _resolver: Self::Resolver, _out: rkyv::Place<Self::Archived>) { match *self {} }
93 }
94
95 #[derive(Debug)]
96 pub enum ArchivedInfallible {}
97
98 unsafe impl rkyv::Portable for ArchivedInfallible {}
99
100 unsafe impl<C: rkyv::rancor::Fallible + ?Sized> rkyv::bytecheck::CheckBytes<C> for ArchivedInfallible {
101 unsafe fn check_bytes(_value: *const Self, _context: &mut C) -> Result<(), C::Error> { Ok(()) }
102 }
103
104 impl<S: rkyv::rancor::Fallible + ?Sized> rkyv::Serialize<S> for Infallible {
105 fn serialize(&self, _serializer: &mut S) -> Result<Self::Resolver, S::Error> { match *self {} }
106 }
107
108 impl<D: rkyv::rancor::Fallible + ?Sized> rkyv::Deserialize<Infallible, D> for ArchivedInfallible {
109 fn deserialize(&self, _deserializer: &mut D) -> Result<Infallible, D::Error> { match *self {} }
110 }
111}
112
113#[test]
114fn cancellation_msg() {
115 let msg = cancellation_message(1, 2);
116 assert_eq!(extract_cancellation_message(&msg).unwrap(), (1, 2));
117}