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(crate) fn postcard_serialize_bytes<T: serde::Serialize, const N: usize>(
24 object: &T,
25) -> postcard::Result<Bytes<N>> {
26 let mut vec = Bytes::new();
27 vec.resize_to_capacity();
28 let serialized = postcard::to_slice(object, &mut vec)?.len();
29 vec.resize(serialized, 0).unwrap();
30 Ok(vec)
31}
32
33pub trait Extension {
35 type Request: DeserializeOwned + Serialize;
37 type Reply: DeserializeOwned + Serialize;
39
40 #[inline(never)]
46 fn serialize_request(
47 id: u8,
48 request: &Self::Request,
49 ) -> Result<request::SerdeExtension, ClientError> {
50 postcard_serialize_bytes(request)
51 .map(|request| request::SerdeExtension { id, request })
52 .map_err(|_| ClientError::SerializationFailed)
53 }
54
55 #[inline(never)]
61 fn deserialize_request(request: &request::SerdeExtension) -> Result<Self::Request, Error> {
62 postcard::from_bytes(&request.request).map_err(|_| Error::InvalidSerializedRequest)
63 }
64
65 #[inline(never)]
71 fn serialize_reply(reply: &Self::Reply) -> Result<reply::SerdeExtension, Error> {
72 postcard_serialize_bytes(reply)
73 .map(|reply| reply::SerdeExtension { reply })
74 .map_err(|_| Error::ReplySerializationFailure)
75 }
76
77 #[inline(never)]
83 fn deserialize_reply(reply: &reply::SerdeExtension) -> Result<Self::Reply, Error> {
84 postcard::from_bytes(&reply.reply).map_err(|_| Error::InvalidSerializedReply)
85 }
86}
87
88pub trait ExtensionClient<E: Extension>: PollClient {
93 fn id() -> u8;
95
96 fn extension<Rq, Rp>(&mut self, request: Rq) -> ExtensionResult<'_, E, Rp, Self>
101 where
102 Rq: Into<E::Request>,
103 Rp: TryFrom<E::Reply, Error = Error>,
104 {
105 let request = E::serialize_request(Self::id(), &request.into())?;
106 self.request(request).map(From::from)
107 }
108}
109
110pub type ExtensionResult<'a, E, T, C> = Result<ExtensionFutureResult<'a, E, T, C>, ClientError>;
112
113#[must_use = "Syscalls must be polled with the `syscall` macro"]
114pub struct ExtensionFutureResult<'c, E, T, C: ?Sized> {
116 client: &'c mut C,
117 __: PhantomData<(E, T)>,
118}
119
120impl<'c, E, T, C: ?Sized> ExtensionFutureResult<'c, E, T, C> {
121 fn new(client: &'c mut C) -> Self {
122 Self {
123 client,
124 __: PhantomData,
125 }
126 }
127}
128
129impl<E, T, C> ExtensionFutureResult<'_, E, T, C>
130where
131 E: Extension,
132 T: TryFrom<E::Reply, Error = Error>,
133 C: PollClient,
134{
135 pub fn poll(&mut self) -> Poll<Result<T, Error>> {
136 self.client.poll().map(|result| {
137 result.and_then(|reply| {
138 let reply = reply::SerdeExtension::try_from(reply)?;
139 let reply: E::Reply = E::deserialize_reply(&reply)?;
140 reply.try_into()
141 })
142 })
143 }
144}
145
146impl<'c, E, T, C> From<FutureResult<'c, reply::SerdeExtension, C>>
147 for ExtensionFutureResult<'c, E, T, C>
148where
149 C: PollClient + ?Sized,
150{
151 fn from(result: FutureResult<'c, reply::SerdeExtension, C>) -> Self {
152 Self::new(result.client)
153 }
154}