trussed_core/
serde_extensions.rs1use core::{marker::PhantomData, task::Poll};
13
14use serde::{de::DeserializeOwned, Serialize};
15
16use crate::{
17 api::{reply, request},
18 client::{ClientError, FutureResult, PollClient},
19 error::Error,
20 types::Bytes,
21};
22
23pub trait Extension {
25 type Request: DeserializeOwned + Serialize;
27 type Reply: DeserializeOwned + Serialize;
29
30 #[inline(never)]
36 fn serialize_request(
37 id: u8,
38 request: &Self::Request,
39 ) -> Result<request::SerdeExtension, ClientError> {
40 postcard::to_vec(request)
41 .map(Bytes::from)
42 .map(|request| request::SerdeExtension { id, request })
43 .map_err(|_| ClientError::SerializationFailed)
44 }
45
46 #[inline(never)]
52 fn deserialize_request(request: &request::SerdeExtension) -> Result<Self::Request, Error> {
53 postcard::from_bytes(&request.request).map_err(|_| Error::InvalidSerializedRequest)
54 }
55
56 #[inline(never)]
62 fn serialize_reply(reply: &Self::Reply) -> Result<reply::SerdeExtension, Error> {
63 postcard::to_vec(reply)
64 .map(Bytes::from)
65 .map(|reply| reply::SerdeExtension { reply })
66 .map_err(|_| Error::ReplySerializationFailure)
67 }
68
69 #[inline(never)]
75 fn deserialize_reply(reply: &reply::SerdeExtension) -> Result<Self::Reply, Error> {
76 postcard::from_bytes(&reply.reply).map_err(|_| Error::InvalidSerializedReply)
77 }
78}
79
80pub trait ExtensionClient<E: Extension>: PollClient {
85 fn id() -> u8;
87
88 fn extension<Rq, Rp>(&mut self, request: Rq) -> ExtensionResult<'_, E, Rp, Self>
93 where
94 Rq: Into<E::Request>,
95 Rp: TryFrom<E::Reply, Error = Error>,
96 {
97 let request = E::serialize_request(Self::id(), &request.into())?;
98 self.request(request).map(From::from)
99 }
100}
101
102pub type ExtensionResult<'a, E, T, C> = Result<ExtensionFutureResult<'a, E, T, C>, ClientError>;
104
105#[must_use = "Syscalls must be polled with the `syscall` macro"]
106pub struct ExtensionFutureResult<'c, E, T, C: ?Sized> {
108 client: &'c mut C,
109 __: PhantomData<(E, T)>,
110}
111
112impl<'c, E, T, C: ?Sized> ExtensionFutureResult<'c, E, T, C> {
113 fn new(client: &'c mut C) -> Self {
114 Self {
115 client,
116 __: PhantomData,
117 }
118 }
119}
120
121impl<E, T, C> ExtensionFutureResult<'_, E, T, C>
122where
123 E: Extension,
124 T: TryFrom<E::Reply, Error = Error>,
125 C: PollClient,
126{
127 pub fn poll(&mut self) -> Poll<Result<T, Error>> {
128 self.client.poll().map(|result| {
129 result.and_then(|reply| {
130 let reply = reply::SerdeExtension::try_from(reply)?;
131 let reply: E::Reply = E::deserialize_reply(&reply)?;
132 reply.try_into()
133 })
134 })
135 }
136}
137
138impl<'c, E, T, C> From<FutureResult<'c, reply::SerdeExtension, C>>
139 for ExtensionFutureResult<'c, E, T, C>
140where
141 C: PollClient + ?Sized,
142{
143 fn from(result: FutureResult<'c, reply::SerdeExtension, C>) -> Self {
144 Self::new(result.client)
145 }
146}