server/event/
mod.rs

1// SPDX-FileCopyrightText: 2023 Foundation Devices, Inc. <hello@foundation.xyz>
2// SPDX-License-Identifier: GPL-3.0-or-later
3pub 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    /// An error type that can never be constructed, similar to std::convert::Infallible
84    /// but with rkyv serialization support.
85    #[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}