pub use fidl::encoding::{decode_transaction_header, Decode, DynamicFlags, TransactionHeader};
use fidl::encoding::{
Decoder, EmptyStruct, Encode, Encoder, Flexible, FlexibleResult, FlexibleResultType,
FlexibleType, FrameworkErr, NoHandleResourceDialect, ResultType, TransactionMessage,
TransactionMessageType, TypeMarker, ValueTypeMarker,
};
use fidl::{new_empty, Error};
pub use fidl::for_fidl_message_crate::Body;
pub use fidl::for_fidl_message_crate::ErrorType;
pub fn encode_message<T: Body>(header: TransactionHeader, body: T) -> Result<Vec<u8>, Error>
where
for<'a> <<T as Body>::MarkerAtTopLevel as ValueTypeMarker>::Borrowed<'a>:
Encode<T::MarkerAtTopLevel, NoHandleResourceDialect>,
{
encode::<T::MarkerAtTopLevel>(header, T::MarkerAtTopLevel::borrow(&body))
}
pub fn encode_response_result<T: Body, E: ErrorType>(
header: TransactionHeader,
result: Result<T, E>,
) -> Result<Vec<u8>, Error>
where
for<'a> <<T as Body>::MarkerInResultUnion as ValueTypeMarker>::Borrowed<'a>:
Encode<T::MarkerInResultUnion, NoHandleResourceDialect>,
for<'a> <<E as ErrorType>::Marker as ValueTypeMarker>::Borrowed<'a>:
Encode<E::Marker, NoHandleResourceDialect>,
{
encode::<FlexibleResultType<T::MarkerInResultUnion, E::Marker>>(
header,
FlexibleResult::new(match result {
Ok(ref body) => Ok(T::MarkerInResultUnion::borrow(body)),
Err(ref e) => Err(E::Marker::borrow(e)),
}),
)
}
pub fn encode_response_flexible<T: Body>(
header: TransactionHeader,
body: T,
) -> Result<Vec<u8>, Error>
where
for<'a> <<T as Body>::MarkerInResultUnion as ValueTypeMarker>::Borrowed<'a>:
Encode<T::MarkerInResultUnion, NoHandleResourceDialect>,
{
encode::<FlexibleType<T::MarkerInResultUnion>>(
header,
Flexible::Ok(T::MarkerInResultUnion::borrow(&body)),
)
}
pub fn encode_response_flexible_unknown(header: TransactionHeader) -> Result<Vec<u8>, Error> {
encode::<FlexibleType<EmptyStruct>>(
header,
Flexible::<()>::FrameworkErr(FrameworkErr::UnknownMethod),
)
}
pub fn decode_message<T: Body>(header: TransactionHeader, body: &[u8]) -> Result<T, Error>
where
<T::MarkerAtTopLevel as TypeMarker>::Owned:
Decode<T::MarkerAtTopLevel, NoHandleResourceDialect>,
{
decode::<T::MarkerAtTopLevel>(header, body)
}
pub fn decode_response_strict_result<T: Body, E: ErrorType>(
header: TransactionHeader,
body: &[u8],
) -> Result<Result<T, E>, Error>
where
<T::MarkerInResultUnion as TypeMarker>::Owned:
Decode<T::MarkerInResultUnion, NoHandleResourceDialect>,
{
decode::<ResultType<T::MarkerInResultUnion, E::Marker>>(header, body)
}
pub enum MaybeUnknown<T> {
Known(T),
Unknown,
}
pub fn decode_response_flexible<T: Body>(
header: TransactionHeader,
body: &[u8],
) -> Result<MaybeUnknown<T>, Error>
where
<T::MarkerInResultUnion as TypeMarker>::Owned:
Decode<T::MarkerInResultUnion, NoHandleResourceDialect>,
{
match decode::<FlexibleType<T::MarkerInResultUnion>>(header, body)? {
Flexible::Ok(value) => Ok(MaybeUnknown::Known(value)),
Flexible::FrameworkErr(err) => match err {
FrameworkErr::UnknownMethod => Ok(MaybeUnknown::Unknown),
},
}
}
pub fn decode_response_flexible_result<T: Body, E: ErrorType>(
header: TransactionHeader,
body: &[u8],
) -> Result<MaybeUnknown<Result<T, E>>, Error>
where
<T::MarkerInResultUnion as TypeMarker>::Owned:
Decode<T::MarkerInResultUnion, NoHandleResourceDialect>,
{
match decode::<FlexibleResultType<T::MarkerInResultUnion, E::Marker>>(header, body)? {
FlexibleResult::Ok(value) => Ok(MaybeUnknown::Known(Ok(value))),
FlexibleResult::DomainErr(err) => Ok(MaybeUnknown::Known(Err(err))),
FlexibleResult::FrameworkErr(err) => match err {
FrameworkErr::UnknownMethod => Ok(MaybeUnknown::Unknown),
},
}
}
fn encode<T: TypeMarker>(
header: TransactionHeader,
body: impl Encode<T, NoHandleResourceDialect>,
) -> Result<Vec<u8>, Error> {
let msg = TransactionMessage { header, body };
let mut combined_bytes = Vec::<u8>::new();
let mut handles = Vec::new();
Encoder::encode::<TransactionMessageType<T>>(&mut combined_bytes, &mut handles, msg)?;
debug_assert!(handles.is_empty(), "value type contains handles");
Ok(combined_bytes)
}
fn decode<T: TypeMarker>(header: TransactionHeader, body: &[u8]) -> Result<T::Owned, Error>
where
T::Owned: Decode<T, NoHandleResourceDialect>,
{
let mut output = new_empty!(T);
Decoder::decode_into::<T>(&header, body, &mut [], &mut output)?;
Ok(output)
}