1pub use fidl::encoding::{decode_transaction_header, Decode, DynamicFlags, TransactionHeader};
23
24use fidl::encoding::{
25 Decoder, EmptyStruct, Encode, Encoder, Flexible, FlexibleResult, FlexibleResultType,
26 FlexibleType, FrameworkErr, NoHandleResourceDialect, ResultType, TransactionMessage,
27 TransactionMessageType, TypeMarker, ValueTypeMarker,
28};
29use fidl::{new_empty, Error};
30
31pub use fidl::for_fidl_message_crate::Body;
34
35pub use fidl::for_fidl_message_crate::ErrorType;
39
40pub fn encode_message<T: Body>(header: TransactionHeader, body: T) -> Result<Vec<u8>, Error>
47where
48 for<'a> <<T as Body>::MarkerAtTopLevel as ValueTypeMarker>::Borrowed<'a>:
49 Encode<T::MarkerAtTopLevel, NoHandleResourceDialect>,
50{
51 encode::<T::MarkerAtTopLevel>(header, T::MarkerAtTopLevel::borrow(&body))
52}
53
54pub fn encode_response_result<T: Body, E: ErrorType>(
57 header: TransactionHeader,
58 result: Result<T, E>,
59) -> Result<Vec<u8>, Error>
60where
61 for<'a> <<T as Body>::MarkerInResultUnion as ValueTypeMarker>::Borrowed<'a>:
62 Encode<T::MarkerInResultUnion, NoHandleResourceDialect>,
63 for<'a> <<E as ErrorType>::Marker as ValueTypeMarker>::Borrowed<'a>:
64 Encode<E::Marker, NoHandleResourceDialect>,
65{
66 encode::<FlexibleResultType<T::MarkerInResultUnion, E::Marker>>(
67 header,
68 FlexibleResult::new(match result {
69 Ok(ref body) => Ok(T::MarkerInResultUnion::borrow(body)),
70 Err(ref e) => Err(E::Marker::borrow(e)),
71 }),
72 )
73}
74
75pub fn encode_response_flexible<T: Body>(
78 header: TransactionHeader,
79 body: T,
80) -> Result<Vec<u8>, Error>
81where
82 for<'a> <<T as Body>::MarkerInResultUnion as ValueTypeMarker>::Borrowed<'a>:
83 Encode<T::MarkerInResultUnion, NoHandleResourceDialect>,
84{
85 encode::<FlexibleType<T::MarkerInResultUnion>>(
86 header,
87 Flexible::Ok(T::MarkerInResultUnion::borrow(&body)),
88 )
89}
90
91pub fn encode_response_flexible_unknown(header: TransactionHeader) -> Result<Vec<u8>, Error> {
94 encode::<FlexibleType<EmptyStruct>>(
95 header,
96 Flexible::<()>::FrameworkErr(FrameworkErr::UnknownMethod),
97 )
98}
99
100pub fn decode_message<T: Body>(header: TransactionHeader, body: &[u8]) -> Result<T, Error>
109where
110 <T::MarkerAtTopLevel as TypeMarker>::Owned:
111 Decode<T::MarkerAtTopLevel, NoHandleResourceDialect>,
112{
113 decode::<T::MarkerAtTopLevel>(header, body)
114}
115
116pub fn decode_response_strict_result<T: Body, E: ErrorType>(
119 header: TransactionHeader,
120 body: &[u8],
121) -> Result<Result<T, E>, Error>
122where
123 <T::MarkerInResultUnion as TypeMarker>::Owned:
124 Decode<T::MarkerInResultUnion, NoHandleResourceDialect>,
125{
126 decode::<ResultType<T::MarkerInResultUnion, E::Marker>>(header, body)
127}
128
129pub enum MaybeUnknown<T> {
131 Known(T),
133 Unknown,
135}
136
137pub fn decode_response_flexible<T: Body>(
140 header: TransactionHeader,
141 body: &[u8],
142) -> Result<MaybeUnknown<T>, Error>
143where
144 <T::MarkerInResultUnion as TypeMarker>::Owned:
145 Decode<T::MarkerInResultUnion, NoHandleResourceDialect>,
146{
147 match decode::<FlexibleType<T::MarkerInResultUnion>>(header, body)? {
148 Flexible::Ok(value) => Ok(MaybeUnknown::Known(value)),
149 Flexible::FrameworkErr(err) => match err {
150 FrameworkErr::UnknownMethod => Ok(MaybeUnknown::Unknown),
151 },
152 }
153}
154
155pub fn decode_response_flexible_result<T: Body, E: ErrorType>(
158 header: TransactionHeader,
159 body: &[u8],
160) -> Result<MaybeUnknown<Result<T, E>>, Error>
161where
162 <T::MarkerInResultUnion as TypeMarker>::Owned:
163 Decode<T::MarkerInResultUnion, NoHandleResourceDialect>,
164{
165 match decode::<FlexibleResultType<T::MarkerInResultUnion, E::Marker>>(header, body)? {
166 FlexibleResult::Ok(value) => Ok(MaybeUnknown::Known(Ok(value))),
167 FlexibleResult::DomainErr(err) => Ok(MaybeUnknown::Known(Err(err))),
168 FlexibleResult::FrameworkErr(err) => match err {
169 FrameworkErr::UnknownMethod => Ok(MaybeUnknown::Unknown),
170 },
171 }
172}
173
174fn encode<T: TypeMarker>(
175 header: TransactionHeader,
176 body: impl Encode<T, NoHandleResourceDialect>,
177) -> Result<Vec<u8>, Error> {
178 let msg = TransactionMessage { header, body };
179 let mut combined_bytes = Vec::<u8>::new();
180 let mut handles = Vec::new();
181 Encoder::encode::<TransactionMessageType<T>>(&mut combined_bytes, &mut handles, msg)?;
182 debug_assert!(handles.is_empty(), "value type contains handles");
183 Ok(combined_bytes)
184}
185
186fn decode<T: TypeMarker>(header: TransactionHeader, body: &[u8]) -> Result<T::Owned, Error>
187where
188 T::Owned: Decode<T, NoHandleResourceDialect>,
189{
190 let mut output = new_empty!(T);
191 Decoder::decode_into::<T>(&header, body, &mut [], &mut output)?;
192 Ok(output)
193}