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