fidl_next_protocol/
buffer.rs

1// Copyright 2024 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use fidl_constants::MAGIC_NUMBER_INITIAL;
6use fidl_next_codec::{
7    DecodeError, DecoderExt as _, EncodeError, EncoderExt as _, WireI32, WireU32, WireU64,
8};
9
10use crate::{
11    MessageHeaderFlags0, MessageHeaderFlags1, MessageHeaderFlags2, Transport, WireEpitaph,
12    WireMessageHeader,
13};
14
15/// The flexibility of a method.
16#[derive(Clone, Copy, Debug)]
17pub enum Flexibility {
18    /// The method is strict.
19    Strict,
20    /// The method is flexible.
21    Flexible,
22}
23
24/// Encodes a message into the given buffer.
25pub fn encode_header<T: Transport>(
26    buffer: &mut T::SendBuffer,
27    txid: u32,
28    ordinal: u64,
29    flexibility: Flexibility,
30) -> Result<(), EncodeError> {
31    buffer.encode_next(
32        WireMessageHeader {
33            txid: WireU32(txid),
34            flags_0: MessageHeaderFlags0::WIRE_FORMAT_V2,
35            flags_1: MessageHeaderFlags1::empty(),
36            flags_2: match flexibility {
37                Flexibility::Strict => MessageHeaderFlags2::empty(),
38                Flexibility::Flexible => MessageHeaderFlags2::FLEXIBLE_METHOD,
39            },
40            magic_number: MAGIC_NUMBER_INITIAL,
41            ordinal: WireU64(ordinal),
42        },
43        (),
44    )
45}
46
47/// Parses the transaction ID and ordinal from the given buffer.
48pub fn decode_header<T: Transport>(
49    mut buffer: &mut T::RecvBuffer,
50) -> Result<(u32, u64, Flexibility), DecodeError> {
51    let header = buffer.decode_owned::<WireMessageHeader>()?;
52
53    let flexibility = if header.flags_2.contains(MessageHeaderFlags2::FLEXIBLE_METHOD) {
54        Flexibility::Flexible
55    } else {
56        Flexibility::Strict
57    };
58
59    Ok((*header.txid, *header.ordinal, flexibility))
60}
61
62/// Encodes an epitaph into the given buffer.
63pub fn encode_epitaph<T: Transport>(
64    buffer: &mut T::SendBuffer,
65    error: i32,
66) -> Result<(), EncodeError> {
67    buffer.encode_next(WireEpitaph { error: WireI32(error) }, ())
68}
69
70/// Parses the epitaph error from the given buffer.
71pub fn decode_epitaph<T: Transport>(mut buffer: &mut T::RecvBuffer) -> Result<i32, DecodeError> {
72    Ok(*buffer.decode_owned::<WireEpitaph>()?.error)
73}