sel4_microkit_message/
lib.rs
1#![no_std]
8
9use core::fmt;
10use core::mem;
11
12#[cfg(feature = "postcard")]
13use serde::{Deserialize, Serialize};
14
15use sel4_microkit_base::{with_msg_bytes, with_msg_bytes_mut, MessageInfo, MessageRegisterValue};
16
17use sel4_microkit_message_types::{
18 EmptyMessage, EmptyMessageValue, MessageLabel, MessageRecv, MessageSend, MessageValueRecv,
19 MessageValueSend, TriviallyLabeled,
20};
21
22#[cfg(feature = "postcard")]
23use sel4_microkit_message_types::MessageValueUsingPostcard;
24
25pub use sel4_microkit_message_types as types;
26
27const MAX_MESSAGE_LABEL: MessageLabel =
28 !0 >> (mem::size_of::<MessageInfo>() * 8 - MessageInfo::label_width());
29
30pub const UNSPECIFIED_ERROR_MESSAGE_LABEL: MessageLabel = MAX_MESSAGE_LABEL;
33
34#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
35pub struct UnspecifiedErrorMessage;
36
37impl From<TriviallyLabeled<EmptyMessageValue, UNSPECIFIED_ERROR_MESSAGE_LABEL>>
38 for UnspecifiedErrorMessage
39{
40 fn from(_: TriviallyLabeled<EmptyMessageValue, UNSPECIFIED_ERROR_MESSAGE_LABEL>) -> Self {
41 Default::default()
42 }
43}
44
45impl From<UnspecifiedErrorMessage>
46 for TriviallyLabeled<EmptyMessageValue, UNSPECIFIED_ERROR_MESSAGE_LABEL>
47{
48 fn from(_: UnspecifiedErrorMessage) -> Self {
49 Default::default()
50 }
51}
52
53impl MessageSend for UnspecifiedErrorMessage {
54 type Label = <TriviallyLabeled<EmptyMessageValue, UNSPECIFIED_ERROR_MESSAGE_LABEL> as MessageSend>::Label;
55
56 type Error = <TriviallyLabeled<EmptyMessageValue, UNSPECIFIED_ERROR_MESSAGE_LABEL> as MessageSend>::Error;
57
58 fn write_message(self, buf: &mut [u8]) -> Result<(Self::Label, usize), Self::Error> {
59 <TriviallyLabeled<EmptyMessageValue, UNSPECIFIED_ERROR_MESSAGE_LABEL>>::from(self)
60 .write_message(buf)
61 }
62}
63
64impl MessageRecv for UnspecifiedErrorMessage {
65 type Label = <TriviallyLabeled<EmptyMessageValue, UNSPECIFIED_ERROR_MESSAGE_LABEL> as MessageRecv>::Label;
66
67 type Error = <TriviallyLabeled<EmptyMessageValue, UNSPECIFIED_ERROR_MESSAGE_LABEL> as MessageRecv>::Error;
68
69 fn read_message(label: Self::Label, buf: &[u8]) -> Result<Self, Self::Error> {
70 <TriviallyLabeled<EmptyMessageValue, UNSPECIFIED_ERROR_MESSAGE_LABEL>>::read_message(
71 label, buf,
72 )
73 .map(Into::into)
74 }
75}
76
77pub trait MessageInfoExt: Sized {
80 fn send<T: MessageSend>(val: T) -> Result<Self, T::Error>;
81
82 fn recv<T: MessageRecv>(self) -> Result<T, MessageRecvErrorFor<T>>;
83
84 fn send_unspecified_error() -> Self {
85 Self::send(UnspecifiedErrorMessage).unwrap_or_else(|absurdity| match absurdity {})
86 }
87
88 fn send_empty() -> Self {
89 Self::send(EmptyMessage).unwrap_or_else(|absurdity| match absurdity {})
90 }
91
92 fn recv_empty(self) -> Result<(), MessageRecvErrorFor<EmptyMessage>> {
93 self.recv().map(|EmptyMessage| ())
94 }
95
96 fn send_with_trivial_label<T: MessageValueSend>(val: T) -> Result<Self, T::Error> {
97 type Helper<T> = TriviallyLabeled<T>; Self::send(Helper::new(val))
99 }
100
101 fn recv_with_trivial_label<T: MessageValueRecv>(
102 self,
103 ) -> Result<T, MessageRecvErrorFor<TriviallyLabeled<T>>> {
104 self.recv().map(TriviallyLabeled::into_inner)
105 }
106
107 #[cfg(feature = "postcard")]
108 fn send_using_postcard<T: Serialize>(
109 val: T,
110 ) -> Result<Self, <MessageValueUsingPostcard<T> as MessageValueSend>::Error> {
111 Self::send_with_trivial_label(MessageValueUsingPostcard(val))
112 }
113
114 #[cfg(feature = "postcard")]
115 fn recv_using_postcard<T: for<'a> Deserialize<'a>>(
116 self,
117 ) -> Result<T, MessageRecvErrorFor<TriviallyLabeled<MessageValueUsingPostcard<T>>>> {
118 self.recv_with_trivial_label()
119 .map(|MessageValueUsingPostcard(val)| val)
120 }
121}
122
123impl MessageInfoExt for MessageInfo {
124 fn send<T: MessageSend>(val: T) -> Result<Self, T::Error> {
125 let (label, num_bytes) = with_msg_bytes_mut(|buf| val.write_message(buf))?;
126 let label = label.into();
127 assert!(label <= MAX_MESSAGE_LABEL);
128 Ok(Self::new(label, bytes_to_mrs(num_bytes)))
130 }
131
132 fn recv<T: MessageRecv>(self) -> Result<T, MessageRecvErrorFor<T>> {
133 let label = self
137 .label()
138 .try_into()
139 .map_err(MessageRecvError::LabelError)?;
140 with_msg_bytes(|buf| T::read_message(label, &buf[..mrs_to_bytes(self.count())]))
141 .map_err(MessageRecvError::ValueError)
142 }
143
144 }
148
149pub type MessageRecvErrorFor<T> = MessageRecvError<
150 <<T as MessageRecv>::Label as TryFrom<MessageLabel>>::Error,
151 <T as MessageRecv>::Error,
152>;
153
154#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
155pub enum MessageRecvError<E1, E2> {
156 LabelError(E1),
157 ValueError(E2),
158 }
160
161impl<E1: fmt::Display, E2: fmt::Display> fmt::Display for MessageRecvError<E1, E2> {
162 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
163 match self {
164 Self::LabelError(err) => write!(f, "label error: {}", err),
165 Self::ValueError(err) => write!(f, "value error: {}", err),
166 }
168 }
169}
170
171fn mrs_to_bytes(num_mrs: usize) -> usize {
172 num_mrs * mem::size_of::<MessageRegisterValue>()
173}
174
175fn bytes_to_mrs(num_bytes: usize) -> usize {
176 let d = mem::size_of::<MessageRegisterValue>();
177 num_bytes.next_multiple_of(d) / d
178}