// WARNING: This file is machine generated by fidlgen.

#![allow(
    unused_parens, // one-element-tuple-case is not a tuple
    unused_mut, // not all args require mutation, but many do
    nonstandard_style, // auto-caps does its best, but is not always successful
)]
#![recursion_limit = "512"]

#[cfg(target_os = "fuchsia")]
#[allow(unused_imports)]
use fuchsia_zircon as zx;

#[allow(unused_imports)]
use {
    bitflags::bitflags,
    fidl::{
        client::{decode_transaction_body_fut, QueryResponseFut},
        encoding::{Decodable as _, Encodable as _},
        endpoints::{ControlHandle as _, Responder as _},
        fidl_bits, fidl_empty_struct, fidl_enum, fidl_struct, fidl_struct_copy, fidl_table,
        fidl_union, wrap_handle_metadata,
    },
    fuchsia_zircon_status as zx_status,
    futures::future::{self, MaybeDone, TryFutureExt},
};

const _FIDL_TRACE_BINDINGS_RUST: u32 = 6;

pub type MainProtocolTwoWayLocalWithErrorResult = Result<(u32, u32), u32>;

/// Handle-type validating wrapper for MainProtocolTwoWayLocalWithErrorResult responses, used internally by
/// FIDL bindings to decode method results. This should only be used by
/// generated APIs, API users should never need to use this type. It is public
/// because it is shared with composed protocols.
#[doc(hidden)]
pub type MainProtocolTwoWayLocalWithErrorResultHandleWrapper = Result<(u32, u32), u32>;

pub type MainProtocolOnLocalWithErrorResult = Result<(u32, u32), u32>;

/// Handle-type validating wrapper for MainProtocolOnLocalWithErrorResult responses, used internally by
/// FIDL bindings to decode method results. This should only be used by
/// generated APIs, API users should never need to use this type. It is public
/// because it is shared with composed protocols.
#[doc(hidden)]
pub type MainProtocolOnLocalWithErrorResultHandleWrapper = Result<(u32, u32), u32>;

pub type MainProtocolTwoWayImportWithErrorResult = Result<(i32), u32>;

/// Handle-type validating wrapper for MainProtocolTwoWayImportWithErrorResult responses, used internally by
/// FIDL bindings to decode method results. This should only be used by
/// generated APIs, API users should never need to use this type. It is public
/// because it is shared with composed protocols.
#[doc(hidden)]
pub type MainProtocolTwoWayImportWithErrorResultHandleWrapper = Result<(i32,), u32>;

pub type MainProtocolOnImportWithErrorResult = Result<(i32), u32>;

/// Handle-type validating wrapper for MainProtocolOnImportWithErrorResult responses, used internally by
/// FIDL bindings to decode method results. This should only be used by
/// generated APIs, API users should never need to use this type. It is public
/// because it is shared with composed protocols.
#[doc(hidden)]
pub type MainProtocolOnImportWithErrorResultHandleWrapper = Result<(i32,), u32>;

pub type MainProtocolTwoWayAnonWithErrorResult = Result<(u32, u32), u32>;

/// Handle-type validating wrapper for MainProtocolTwoWayAnonWithErrorResult responses, used internally by
/// FIDL bindings to decode method results. This should only be used by
/// generated APIs, API users should never need to use this type. It is public
/// because it is shared with composed protocols.
#[doc(hidden)]
pub type MainProtocolTwoWayAnonWithErrorResultHandleWrapper = Result<(u32, u32), u32>;

pub type MainProtocolOnAnonWithErrorResult = Result<(u32, u32), u32>;

/// Handle-type validating wrapper for MainProtocolOnAnonWithErrorResult responses, used internally by
/// FIDL bindings to decode method results. This should only be used by
/// generated APIs, API users should never need to use this type. It is public
/// because it is shared with composed protocols.
#[doc(hidden)]
pub type MainProtocolOnAnonWithErrorResultHandleWrapper = Result<(u32, u32), u32>;

#[derive(
    Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, zerocopy::AsBytes, zerocopy::FromBytes,
)]
#[repr(C)]
pub struct LocalStructPayload {
    pub a: u32,
    pub b: u32,
}

impl fidl::encoding::Persistable for LocalStructPayload {}

fidl_struct_copy! {
    name: LocalStructPayload,
    members: [
        a {
            ty: u32,
            offset_v1: 0,
            offset_v2: 0,
        },
        b {
            ty: u32,
            offset_v1: 4,
            offset_v2: 4,
        },
    ],
    padding_v1: [],
    padding_v2: [],
    size_v1: 8,
    size_v2: 8,
    align_v1: 4,
    align_v2: 4,
}

#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct MainProtocolMarker;

impl fidl::endpoints::ProtocolMarker for MainProtocolMarker {
    type Proxy = MainProtocolProxy;
    type RequestStream = MainProtocolRequestStream;
    const DEBUG_NAME: &'static str = "(anonymous) MainProtocol";
}

pub trait MainProtocolProxyInterface: Send + Sync {
    fn r#one_way_composed(&self, a: i32) -> Result<(), fidl::Error>;
    type TwoWayComposedResponseFut: std::future::Future<Output = Result<(i32), fidl::Error>> + Send;
    fn r#two_way_composed(&self, a: i32) -> Self::TwoWayComposedResponseFut;
    type TwoWayComposedWithErrorResponseFut: std::future::Future<Output = Result<(fidl_test_protocolpayloads_imported::ComposedProtocolTwoWayComposedWithErrorResult), fidl::Error>> + Send;
    fn r#two_way_composed_with_error(&self, a: i32) -> Self::TwoWayComposedWithErrorResponseFut;
    type OnComposedResponseFut: std::future::Future<Output = Result<(i32), fidl::Error>> + Send;
    type OnComposedWithErrorResponseFut: std::future::Future<
            Output = Result<
                (fidl_test_protocolpayloads_imported::ComposedProtocolOnComposedWithErrorResult),
                fidl::Error,
            >,
        > + Send;
    fn r#one_way_local(&self, a: u32, b: u32) -> Result<(), fidl::Error>;
    type TwoWayLocalResponseFut: std::future::Future<Output = Result<(u32, u32), fidl::Error>>
        + Send;
    fn r#two_way_local(&self, a: u32, b: u32) -> Self::TwoWayLocalResponseFut;
    type TwoWayLocalWithErrorResponseFut: std::future::Future<Output = Result<(MainProtocolTwoWayLocalWithErrorResult), fidl::Error>>
        + Send;
    fn r#two_way_local_with_error(&self, a: u32, b: u32) -> Self::TwoWayLocalWithErrorResponseFut;
    type OnLocalResponseFut: std::future::Future<Output = Result<(u32, u32), fidl::Error>> + Send;
    type OnLocalWithErrorResponseFut: std::future::Future<Output = Result<(MainProtocolOnLocalWithErrorResult), fidl::Error>>
        + Send;
    fn r#one_way_import(&self, a: i32) -> Result<(), fidl::Error>;
    type TwoWayImportResponseFut: std::future::Future<Output = Result<(i32), fidl::Error>> + Send;
    fn r#two_way_import(&self, a: i32) -> Self::TwoWayImportResponseFut;
    type TwoWayImportWithErrorResponseFut: std::future::Future<Output = Result<(MainProtocolTwoWayImportWithErrorResult), fidl::Error>>
        + Send;
    fn r#two_way_import_with_error(&self, a: i32) -> Self::TwoWayImportWithErrorResponseFut;
    type OnImportResponseFut: std::future::Future<Output = Result<(i32), fidl::Error>> + Send;
    type OnImportWithErrorResponseFut: std::future::Future<Output = Result<(MainProtocolOnImportWithErrorResult), fidl::Error>>
        + Send;
    fn r#one_way_anon(&self, a: u32, b: u32) -> Result<(), fidl::Error>;
    type TwoWayAnonResponseFut: std::future::Future<Output = Result<(u32, u32), fidl::Error>> + Send;
    fn r#two_way_anon(&self, a: u32, b: u32) -> Self::TwoWayAnonResponseFut;
    type TwoWayAnonWithErrorResponseFut: std::future::Future<Output = Result<(MainProtocolTwoWayAnonWithErrorResult), fidl::Error>>
        + Send;
    fn r#two_way_anon_with_error(&self, a: u32, b: u32) -> Self::TwoWayAnonWithErrorResponseFut;
    type OnAnonResponseFut: std::future::Future<Output = Result<(u32, u32), fidl::Error>> + Send;
    type OnAnonWithErrorResponseFut: std::future::Future<Output = Result<(MainProtocolOnAnonWithErrorResult), fidl::Error>>
        + Send;
}

#[derive(Debug)]
#[cfg(target_os = "fuchsia")]
pub struct MainProtocolSynchronousProxy {
    client: fidl::client::sync::Client,
}

#[cfg(target_os = "fuchsia")]
impl MainProtocolSynchronousProxy {
    pub fn new(channel: fidl::Channel) -> Self {
        let protocol_name = <MainProtocolMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
        Self { client: fidl::client::sync::Client::new(channel, protocol_name) }
    }

    pub fn into_channel(self) -> fidl::Channel {
        self.client.into_channel()
    }

    /// Waits until an event arrives and returns it. It is safe for other
    /// threads to make concurrent requests while waiting for an event.
    pub fn wait_for_event(&self, deadline: zx::Time) -> Result<MainProtocolEvent, fidl::Error> {
        MainProtocolEvent::decode(self.client.wait_for_event(deadline)?)
    }
    pub fn r#one_way_composed(&self, mut a: i32) -> Result<(), fidl::Error> {
        self.client.send(&mut (a,), 0x241e4384443ccb10, fidl::encoding::DynamicFlags::empty())
    }
    pub fn r#two_way_composed(
        &self,
        mut a: i32,
        ___deadline: zx::Time,
    ) -> Result<(i32), fidl::Error> {
        let _value: (i32,) = self.client.send_query(
            &mut (a),
            0x2348a1331ca4cfb0,
            fidl::encoding::DynamicFlags::empty(),
            ___deadline,
        )?;
        Ok(_value.0)
    }
    pub fn r#two_way_composed_with_error(
        &self,
        mut a: i32,
        ___deadline: zx::Time,
    ) -> Result<
        (fidl_test_protocolpayloads_imported::ComposedProtocolTwoWayComposedWithErrorResult),
        fidl::Error,
    > {
        let _value: fidl_test_protocolpayloads_imported::ComposedProtocolTwoWayComposedWithErrorResultHandleWrapper = self.client.send_query(&mut (a),
                0x6a9be48b574d1557,
                fidl::encoding::DynamicFlags::empty(),
                ___deadline,
            )?;
        Ok(_value.map(|_value| _value.0))
    }
    pub fn r#one_way_local(&self, mut a: u32, mut b: u32) -> Result<(), fidl::Error> {
        self.client.send(&mut (a, b), 0x6b9feaf9305b0715, fidl::encoding::DynamicFlags::empty())
    }
    pub fn r#two_way_local(
        &self,
        mut a: u32,
        mut b: u32,
        ___deadline: zx::Time,
    ) -> Result<(u32, u32), fidl::Error> {
        let _value: (u32, u32) = self.client.send_query(
            &mut (a, b),
            0x743776548de3af0f,
            fidl::encoding::DynamicFlags::empty(),
            ___deadline,
        )?;
        Ok((_value.0, _value.1))
    }
    pub fn r#two_way_local_with_error(
        &self,
        mut a: u32,
        mut b: u32,
        ___deadline: zx::Time,
    ) -> Result<(MainProtocolTwoWayLocalWithErrorResult), fidl::Error> {
        let _value: MainProtocolTwoWayLocalWithErrorResultHandleWrapper = self.client.send_query(
            &mut (a, b),
            0x2839c029915cb8fc,
            fidl::encoding::DynamicFlags::empty(),
            ___deadline,
        )?;
        Ok(_value.map(|_value| (_value.0, _value.1)))
    }
    pub fn r#one_way_import(&self, mut a: i32) -> Result<(), fidl::Error> {
        self.client.send(&mut (a,), 0x2e6b091ae4cee40c, fidl::encoding::DynamicFlags::empty())
    }
    pub fn r#two_way_import(
        &self,
        mut a: i32,
        ___deadline: zx::Time,
    ) -> Result<(i32), fidl::Error> {
        let _value: (i32,) = self.client.send_query(
            &mut (a),
            0x20f4a8f65ff69473,
            fidl::encoding::DynamicFlags::empty(),
            ___deadline,
        )?;
        Ok(_value.0)
    }
    pub fn r#two_way_import_with_error(
        &self,
        mut a: i32,
        ___deadline: zx::Time,
    ) -> Result<(MainProtocolTwoWayImportWithErrorResult), fidl::Error> {
        let _value: MainProtocolTwoWayImportWithErrorResultHandleWrapper = self.client.send_query(
            &mut (a),
            0x3b7b706d42eb9bbd,
            fidl::encoding::DynamicFlags::empty(),
            ___deadline,
        )?;
        Ok(_value.map(|_value| _value.0))
    }
    pub fn r#one_way_anon(&self, mut a: u32, mut b: u32) -> Result<(), fidl::Error> {
        self.client.send(&mut (a, b), 0xb43565c01ab54ac, fidl::encoding::DynamicFlags::empty())
    }
    pub fn r#two_way_anon(
        &self,
        mut a: u32,
        mut b: u32,
        ___deadline: zx::Time,
    ) -> Result<(u32, u32), fidl::Error> {
        let _value: (u32, u32) = self.client.send_query(
            &mut (a, b),
            0x8bdc969ff7dd759,
            fidl::encoding::DynamicFlags::empty(),
            ___deadline,
        )?;
        Ok((_value.0, _value.1))
    }
    pub fn r#two_way_anon_with_error(
        &self,
        mut a: u32,
        mut b: u32,
        ___deadline: zx::Time,
    ) -> Result<(MainProtocolTwoWayAnonWithErrorResult), fidl::Error> {
        let _value: MainProtocolTwoWayAnonWithErrorResultHandleWrapper = self.client.send_query(
            &mut (a, b),
            0x5862bf8170c87a36,
            fidl::encoding::DynamicFlags::empty(),
            ___deadline,
        )?;
        Ok(_value.map(|_value| (_value.0, _value.1)))
    }
}

#[derive(Debug, Clone)]
pub struct MainProtocolProxy {
    client: fidl::client::Client,
}

impl fidl::endpoints::Proxy for MainProtocolProxy {
    type Protocol = MainProtocolMarker;

    fn from_channel(inner: fidl::AsyncChannel) -> Self {
        Self::new(inner)
    }

    fn into_channel(self) -> Result<::fidl::AsyncChannel, Self> {
        self.client.into_channel().map_err(|client| Self { client })
    }

    fn as_channel(&self) -> &::fidl::AsyncChannel {
        self.client.as_channel()
    }
}

impl MainProtocolProxy {
    /// Create a new Proxy for MainProtocol
    pub fn new(channel: fidl::AsyncChannel) -> Self {
        let protocol_name = <MainProtocolMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
        Self { client: fidl::client::Client::new(channel, protocol_name) }
    }

    /// Get a Stream of events from the remote end of the MainProtocol protocol
    ///
    /// # Panics
    ///
    /// Panics if the event stream was already taken.
    pub fn take_event_stream(&self) -> MainProtocolEventStream {
        MainProtocolEventStream { event_receiver: self.client.take_event_receiver() }
    }
    pub fn r#one_way_composed(&self, mut a: i32) -> Result<(), fidl::Error> {
        MainProtocolProxyInterface::r#one_way_composed(self, a)
    }
    pub fn r#two_way_composed(&self, mut a: i32) -> fidl::client::QueryResponseFut<(i32)> {
        MainProtocolProxyInterface::r#two_way_composed(self, a)
    }
    pub fn r#two_way_composed_with_error(
        &self,
        mut a: i32,
    ) -> fidl::client::QueryResponseFut<
        (fidl_test_protocolpayloads_imported::ComposedProtocolTwoWayComposedWithErrorResult),
    > {
        MainProtocolProxyInterface::r#two_way_composed_with_error(self, a)
    }
    pub fn r#one_way_local(&self, mut a: u32, mut b: u32) -> Result<(), fidl::Error> {
        MainProtocolProxyInterface::r#one_way_local(self, a, b)
    }
    pub fn r#two_way_local(
        &self,
        mut a: u32,
        mut b: u32,
    ) -> fidl::client::QueryResponseFut<(u32, u32)> {
        MainProtocolProxyInterface::r#two_way_local(self, a, b)
    }
    pub fn r#two_way_local_with_error(
        &self,
        mut a: u32,
        mut b: u32,
    ) -> fidl::client::QueryResponseFut<(MainProtocolTwoWayLocalWithErrorResult)> {
        MainProtocolProxyInterface::r#two_way_local_with_error(self, a, b)
    }
    pub fn r#one_way_import(&self, mut a: i32) -> Result<(), fidl::Error> {
        MainProtocolProxyInterface::r#one_way_import(self, a)
    }
    pub fn r#two_way_import(&self, mut a: i32) -> fidl::client::QueryResponseFut<(i32)> {
        MainProtocolProxyInterface::r#two_way_import(self, a)
    }
    pub fn r#two_way_import_with_error(
        &self,
        mut a: i32,
    ) -> fidl::client::QueryResponseFut<(MainProtocolTwoWayImportWithErrorResult)> {
        MainProtocolProxyInterface::r#two_way_import_with_error(self, a)
    }
    pub fn r#one_way_anon(&self, mut a: u32, mut b: u32) -> Result<(), fidl::Error> {
        MainProtocolProxyInterface::r#one_way_anon(self, a, b)
    }
    pub fn r#two_way_anon(
        &self,
        mut a: u32,
        mut b: u32,
    ) -> fidl::client::QueryResponseFut<(u32, u32)> {
        MainProtocolProxyInterface::r#two_way_anon(self, a, b)
    }
    pub fn r#two_way_anon_with_error(
        &self,
        mut a: u32,
        mut b: u32,
    ) -> fidl::client::QueryResponseFut<(MainProtocolTwoWayAnonWithErrorResult)> {
        MainProtocolProxyInterface::r#two_way_anon_with_error(self, a, b)
    }
}

impl MainProtocolProxyInterface for MainProtocolProxy {
    fn r#one_way_composed(&self, mut a: i32) -> Result<(), fidl::Error> {
        self.client.send(&mut (a), 0x241e4384443ccb10, fidl::encoding::DynamicFlags::empty())
    }
    type TwoWayComposedResponseFut = fidl::client::QueryResponseFut<(i32)>;
    fn r#two_way_composed(&self, mut a: i32) -> Self::TwoWayComposedResponseFut {
        fn transform(result: Result<(i32,), fidl::Error>) -> Result<(i32), fidl::Error> {
            result.map(|_value| _value.0)
        }
        let send_result = self.client.call_send_raw_query(
            &mut (a),
            0x2348a1331ca4cfb0,
            fidl::encoding::DynamicFlags::empty(),
        );
        QueryResponseFut(match send_result {
            Ok(res_fut) => future::maybe_done(
                res_fut.and_then(|buf| decode_transaction_body_fut(buf, transform)),
            ),
            Err(e) => MaybeDone::Done(Err(e)),
        })
    }
    type TwoWayComposedWithErrorResponseFut = fidl::client::QueryResponseFut<
        (fidl_test_protocolpayloads_imported::ComposedProtocolTwoWayComposedWithErrorResult),
    >;
    fn r#two_way_composed_with_error(
        &self,
        mut a: i32,
    ) -> Self::TwoWayComposedWithErrorResponseFut {
        fn transform(
            result: Result<fidl_test_protocolpayloads_imported::ComposedProtocolTwoWayComposedWithErrorResultHandleWrapper, fidl::Error>,
        ) -> Result<
            (fidl_test_protocolpayloads_imported::ComposedProtocolTwoWayComposedWithErrorResult),
            fidl::Error,
        > {
            result.map(|_value| _value.map(|_value| _value.0))
        }
        let send_result = self.client.call_send_raw_query(
            &mut (a),
            0x6a9be48b574d1557,
            fidl::encoding::DynamicFlags::empty(),
        );
        QueryResponseFut(match send_result {
            Ok(res_fut) => future::maybe_done(
                res_fut.and_then(|buf| decode_transaction_body_fut(buf, transform)),
            ),
            Err(e) => MaybeDone::Done(Err(e)),
        })
    }
    type OnComposedResponseFut = fidl::client::QueryResponseFut<(i32)>;
    type OnComposedWithErrorResponseFut = fidl::client::QueryResponseFut<
        (fidl_test_protocolpayloads_imported::ComposedProtocolOnComposedWithErrorResult),
    >;
    fn r#one_way_local(&self, mut a: u32, mut b: u32) -> Result<(), fidl::Error> {
        self.client.send(&mut (a, b), 0x6b9feaf9305b0715, fidl::encoding::DynamicFlags::empty())
    }
    type TwoWayLocalResponseFut = fidl::client::QueryResponseFut<(u32, u32)>;
    fn r#two_way_local(&self, mut a: u32, mut b: u32) -> Self::TwoWayLocalResponseFut {
        fn transform(result: Result<(u32, u32), fidl::Error>) -> Result<(u32, u32), fidl::Error> {
            result.map(|_value| (_value.0, _value.1))
        }
        let send_result = self.client.call_send_raw_query(
            &mut (a, b),
            0x743776548de3af0f,
            fidl::encoding::DynamicFlags::empty(),
        );
        QueryResponseFut(match send_result {
            Ok(res_fut) => future::maybe_done(
                res_fut.and_then(|buf| decode_transaction_body_fut(buf, transform)),
            ),
            Err(e) => MaybeDone::Done(Err(e)),
        })
    }
    type TwoWayLocalWithErrorResponseFut =
        fidl::client::QueryResponseFut<(MainProtocolTwoWayLocalWithErrorResult)>;
    fn r#two_way_local_with_error(
        &self,
        mut a: u32,
        mut b: u32,
    ) -> Self::TwoWayLocalWithErrorResponseFut {
        fn transform(
            result: Result<MainProtocolTwoWayLocalWithErrorResultHandleWrapper, fidl::Error>,
        ) -> Result<(MainProtocolTwoWayLocalWithErrorResult), fidl::Error> {
            result.map(|_value| _value.map(|_value| (_value.0, _value.1)))
        }
        let send_result = self.client.call_send_raw_query(
            &mut (a, b),
            0x2839c029915cb8fc,
            fidl::encoding::DynamicFlags::empty(),
        );
        QueryResponseFut(match send_result {
            Ok(res_fut) => future::maybe_done(
                res_fut.and_then(|buf| decode_transaction_body_fut(buf, transform)),
            ),
            Err(e) => MaybeDone::Done(Err(e)),
        })
    }
    type OnLocalResponseFut = fidl::client::QueryResponseFut<(u32, u32)>;
    type OnLocalWithErrorResponseFut =
        fidl::client::QueryResponseFut<(MainProtocolOnLocalWithErrorResult)>;
    fn r#one_way_import(&self, mut a: i32) -> Result<(), fidl::Error> {
        self.client.send(&mut (a), 0x2e6b091ae4cee40c, fidl::encoding::DynamicFlags::empty())
    }
    type TwoWayImportResponseFut = fidl::client::QueryResponseFut<(i32)>;
    fn r#two_way_import(&self, mut a: i32) -> Self::TwoWayImportResponseFut {
        fn transform(result: Result<(i32,), fidl::Error>) -> Result<(i32), fidl::Error> {
            result.map(|_value| _value.0)
        }
        let send_result = self.client.call_send_raw_query(
            &mut (a),
            0x20f4a8f65ff69473,
            fidl::encoding::DynamicFlags::empty(),
        );
        QueryResponseFut(match send_result {
            Ok(res_fut) => future::maybe_done(
                res_fut.and_then(|buf| decode_transaction_body_fut(buf, transform)),
            ),
            Err(e) => MaybeDone::Done(Err(e)),
        })
    }
    type TwoWayImportWithErrorResponseFut =
        fidl::client::QueryResponseFut<(MainProtocolTwoWayImportWithErrorResult)>;
    fn r#two_way_import_with_error(&self, mut a: i32) -> Self::TwoWayImportWithErrorResponseFut {
        fn transform(
            result: Result<MainProtocolTwoWayImportWithErrorResultHandleWrapper, fidl::Error>,
        ) -> Result<(MainProtocolTwoWayImportWithErrorResult), fidl::Error> {
            result.map(|_value| _value.map(|_value| _value.0))
        }
        let send_result = self.client.call_send_raw_query(
            &mut (a),
            0x3b7b706d42eb9bbd,
            fidl::encoding::DynamicFlags::empty(),
        );
        QueryResponseFut(match send_result {
            Ok(res_fut) => future::maybe_done(
                res_fut.and_then(|buf| decode_transaction_body_fut(buf, transform)),
            ),
            Err(e) => MaybeDone::Done(Err(e)),
        })
    }
    type OnImportResponseFut = fidl::client::QueryResponseFut<(i32)>;
    type OnImportWithErrorResponseFut =
        fidl::client::QueryResponseFut<(MainProtocolOnImportWithErrorResult)>;
    fn r#one_way_anon(&self, mut a: u32, mut b: u32) -> Result<(), fidl::Error> {
        self.client.send(&mut (a, b), 0xb43565c01ab54ac, fidl::encoding::DynamicFlags::empty())
    }
    type TwoWayAnonResponseFut = fidl::client::QueryResponseFut<(u32, u32)>;
    fn r#two_way_anon(&self, mut a: u32, mut b: u32) -> Self::TwoWayAnonResponseFut {
        fn transform(result: Result<(u32, u32), fidl::Error>) -> Result<(u32, u32), fidl::Error> {
            result.map(|_value| (_value.0, _value.1))
        }
        let send_result = self.client.call_send_raw_query(
            &mut (a, b),
            0x8bdc969ff7dd759,
            fidl::encoding::DynamicFlags::empty(),
        );
        QueryResponseFut(match send_result {
            Ok(res_fut) => future::maybe_done(
                res_fut.and_then(|buf| decode_transaction_body_fut(buf, transform)),
            ),
            Err(e) => MaybeDone::Done(Err(e)),
        })
    }
    type TwoWayAnonWithErrorResponseFut =
        fidl::client::QueryResponseFut<(MainProtocolTwoWayAnonWithErrorResult)>;
    fn r#two_way_anon_with_error(
        &self,
        mut a: u32,
        mut b: u32,
    ) -> Self::TwoWayAnonWithErrorResponseFut {
        fn transform(
            result: Result<MainProtocolTwoWayAnonWithErrorResultHandleWrapper, fidl::Error>,
        ) -> Result<(MainProtocolTwoWayAnonWithErrorResult), fidl::Error> {
            result.map(|_value| _value.map(|_value| (_value.0, _value.1)))
        }
        let send_result = self.client.call_send_raw_query(
            &mut (a, b),
            0x5862bf8170c87a36,
            fidl::encoding::DynamicFlags::empty(),
        );
        QueryResponseFut(match send_result {
            Ok(res_fut) => future::maybe_done(
                res_fut.and_then(|buf| decode_transaction_body_fut(buf, transform)),
            ),
            Err(e) => MaybeDone::Done(Err(e)),
        })
    }
    type OnAnonResponseFut = fidl::client::QueryResponseFut<(u32, u32)>;
    type OnAnonWithErrorResponseFut =
        fidl::client::QueryResponseFut<(MainProtocolOnAnonWithErrorResult)>;
}

pub struct MainProtocolEventStream {
    event_receiver: fidl::client::EventReceiver,
}

impl std::marker::Unpin for MainProtocolEventStream {}

impl futures::stream::FusedStream for MainProtocolEventStream {
    fn is_terminated(&self) -> bool {
        self.event_receiver.is_terminated()
    }
}

impl futures::Stream for MainProtocolEventStream {
    type Item = Result<MainProtocolEvent, fidl::Error>;

    fn poll_next(
        mut self: std::pin::Pin<&mut Self>,
        cx: &mut std::task::Context<'_>,
    ) -> std::task::Poll<Option<Self::Item>> {
        let buf = match futures::ready!(futures::stream::StreamExt::poll_next_unpin(
            &mut self.event_receiver,
            cx
        )?) {
            Some(buf) => buf,
            None => return std::task::Poll::Ready(None),
        };

        std::task::Poll::Ready(Some(MainProtocolEvent::decode(buf)))
    }
}

#[derive(Debug)]
pub enum MainProtocolEvent {
    OnComposed {
        a: i32,
    },

    OnComposedWithError {
        result: fidl_test_protocolpayloads_imported::ComposedProtocolOnComposedWithErrorResult,
    },

    OnLocal {
        a: u32,

        b: u32,
    },

    OnLocalWithError {
        result: MainProtocolOnLocalWithErrorResult,
    },

    OnImport {
        a: i32,
    },

    OnImportWithError {
        result: MainProtocolOnImportWithErrorResult,
    },

    OnAnon {
        a: u32,

        b: u32,
    },

    OnAnonWithError {
        result: MainProtocolOnAnonWithErrorResult,
    },
}

impl MainProtocolEvent {
    #[allow(irrefutable_let_patterns)]
    pub fn into_on_composed(self) -> Option<(i32)> {
        if let MainProtocolEvent::OnComposed { a } = self {
            Some((a))
        } else {
            None
        }
    }

    #[allow(irrefutable_let_patterns)]
    pub fn into_on_composed_with_error(
        self,
    ) -> Option<(fidl_test_protocolpayloads_imported::ComposedProtocolOnComposedWithErrorResult)>
    {
        if let MainProtocolEvent::OnComposedWithError { result } = self {
            Some((result))
        } else {
            None
        }
    }

    #[allow(irrefutable_let_patterns)]
    pub fn into_on_local(self) -> Option<(u32, u32)> {
        if let MainProtocolEvent::OnLocal { a, b } = self {
            Some((a, b))
        } else {
            None
        }
    }

    #[allow(irrefutable_let_patterns)]
    pub fn into_on_local_with_error(self) -> Option<(MainProtocolOnLocalWithErrorResult)> {
        if let MainProtocolEvent::OnLocalWithError { result } = self {
            Some((result))
        } else {
            None
        }
    }

    #[allow(irrefutable_let_patterns)]
    pub fn into_on_import(self) -> Option<(i32)> {
        if let MainProtocolEvent::OnImport { a } = self {
            Some((a))
        } else {
            None
        }
    }

    #[allow(irrefutable_let_patterns)]
    pub fn into_on_import_with_error(self) -> Option<(MainProtocolOnImportWithErrorResult)> {
        if let MainProtocolEvent::OnImportWithError { result } = self {
            Some((result))
        } else {
            None
        }
    }

    #[allow(irrefutable_let_patterns)]
    pub fn into_on_anon(self) -> Option<(u32, u32)> {
        if let MainProtocolEvent::OnAnon { a, b } = self {
            Some((a, b))
        } else {
            None
        }
    }

    #[allow(irrefutable_let_patterns)]
    pub fn into_on_anon_with_error(self) -> Option<(MainProtocolOnAnonWithErrorResult)> {
        if let MainProtocolEvent::OnAnonWithError { result } = self {
            Some((result))
        } else {
            None
        }
    }

    fn decode(mut buf: fidl::MessageBufEtc) -> Result<MainProtocolEvent, fidl::Error> {
        let (bytes, _handles) = buf.split_mut();
        let (tx_header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;

        match tx_header.ordinal() {
            0x19fbe2b2f6f9273a => {
                let mut out_tuple: (i32,) = fidl::encoding::Decodable::new_empty();
                fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "test.protocolpayloads/MainProtocolOnComposedEvent");
                fidl::trace_blob!("fidl:blob", "decode", bytes);
                fidl::encoding::Decoder::decode_into(
                    &tx_header,
                    _body_bytes,
                    _handles,
                    &mut out_tuple,
                )?;
                fidl::duration_end!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => bytes.len() as u32, "handle_count" => _handles.len() as u32);
                Ok((MainProtocolEvent::OnComposed { a: out_tuple.0 }))
            }
            0x63774db677215e98 => {
                let mut out_tuple: (
                    fidl_test_protocolpayloads_imported::ComposedProtocolOnComposedWithErrorResult,
                ) = fidl::encoding::Decodable::new_empty();
                fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "test.protocolpayloads/MainProtocolOnComposedWithErrorEvent");
                fidl::trace_blob!("fidl:blob", "decode", bytes);
                fidl::encoding::Decoder::decode_into(
                    &tx_header,
                    _body_bytes,
                    _handles,
                    &mut out_tuple,
                )?;
                fidl::duration_end!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => bytes.len() as u32, "handle_count" => _handles.len() as u32);
                Ok((MainProtocolEvent::OnComposedWithError { result: out_tuple.0 }))
            }
            0x4745f7438cd80819 => {
                let mut out_tuple: (u32, u32) = fidl::encoding::Decodable::new_empty();
                fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "test.protocolpayloads/MainProtocolOnLocalEvent");
                fidl::trace_blob!("fidl:blob", "decode", bytes);
                fidl::encoding::Decoder::decode_into(
                    &tx_header,
                    _body_bytes,
                    _handles,
                    &mut out_tuple,
                )?;
                fidl::duration_end!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => bytes.len() as u32, "handle_count" => _handles.len() as u32);
                Ok((MainProtocolEvent::OnLocal { a: out_tuple.0, b: out_tuple.1 }))
            }
            0x4ecd4b3982e221af => {
                let mut out_tuple: (MainProtocolOnLocalWithErrorResult,) =
                    fidl::encoding::Decodable::new_empty();
                fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "test.protocolpayloads/MainProtocolOnLocalWithErrorEvent");
                fidl::trace_blob!("fidl:blob", "decode", bytes);
                fidl::encoding::Decoder::decode_into(
                    &tx_header,
                    _body_bytes,
                    _handles,
                    &mut out_tuple,
                )?;
                fidl::duration_end!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => bytes.len() as u32, "handle_count" => _handles.len() as u32);
                Ok((MainProtocolEvent::OnLocalWithError { result: out_tuple.0 }))
            }
            0x1bb4f4c30b6f8909 => {
                let mut out_tuple: (i32,) = fidl::encoding::Decodable::new_empty();
                fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "test.protocolpayloads/MainProtocolOnImportEvent");
                fidl::trace_blob!("fidl:blob", "decode", bytes);
                fidl::encoding::Decoder::decode_into(
                    &tx_header,
                    _body_bytes,
                    _handles,
                    &mut out_tuple,
                )?;
                fidl::duration_end!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => bytes.len() as u32, "handle_count" => _handles.len() as u32);
                Ok((MainProtocolEvent::OnImport { a: out_tuple.0 }))
            }
            0x6292b793d728f205 => {
                let mut out_tuple: (MainProtocolOnImportWithErrorResult,) =
                    fidl::encoding::Decodable::new_empty();
                fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "test.protocolpayloads/MainProtocolOnImportWithErrorEvent");
                fidl::trace_blob!("fidl:blob", "decode", bytes);
                fidl::encoding::Decoder::decode_into(
                    &tx_header,
                    _body_bytes,
                    _handles,
                    &mut out_tuple,
                )?;
                fidl::duration_end!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => bytes.len() as u32, "handle_count" => _handles.len() as u32);
                Ok((MainProtocolEvent::OnImportWithError { result: out_tuple.0 }))
            }
            0x42d321dacc4df000 => {
                let mut out_tuple: (u32, u32) = fidl::encoding::Decodable::new_empty();
                fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "test.protocolpayloads/MainProtocolOnAnonEvent");
                fidl::trace_blob!("fidl:blob", "decode", bytes);
                fidl::encoding::Decoder::decode_into(
                    &tx_header,
                    _body_bytes,
                    _handles,
                    &mut out_tuple,
                )?;
                fidl::duration_end!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => bytes.len() as u32, "handle_count" => _handles.len() as u32);
                Ok((MainProtocolEvent::OnAnon { a: out_tuple.0, b: out_tuple.1 }))
            }
            0x45bc24ef47b44a02 => {
                let mut out_tuple: (MainProtocolOnAnonWithErrorResult,) =
                    fidl::encoding::Decodable::new_empty();
                fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "test.protocolpayloads/MainProtocolOnAnonWithErrorEvent");
                fidl::trace_blob!("fidl:blob", "decode", bytes);
                fidl::encoding::Decoder::decode_into(
                    &tx_header,
                    _body_bytes,
                    _handles,
                    &mut out_tuple,
                )?;
                fidl::duration_end!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => bytes.len() as u32, "handle_count" => _handles.len() as u32);
                Ok((MainProtocolEvent::OnAnonWithError { result: out_tuple.0 }))
            }
            _ => Err(fidl::Error::UnknownOrdinal {
                ordinal: tx_header.ordinal(),
                protocol_name: <MainProtocolMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
            }),
        }
    }
}

/// A Stream of incoming requests for MainProtocol
pub struct MainProtocolRequestStream {
    inner: std::sync::Arc<fidl::ServeInner>,
    is_terminated: bool,
}

impl std::marker::Unpin for MainProtocolRequestStream {}

impl futures::stream::FusedStream for MainProtocolRequestStream {
    fn is_terminated(&self) -> bool {
        self.is_terminated
    }
}

impl fidl::endpoints::RequestStream for MainProtocolRequestStream {
    type Protocol = MainProtocolMarker;
    type ControlHandle = MainProtocolControlHandle;

    fn from_channel(channel: fidl::AsyncChannel) -> Self {
        Self { inner: std::sync::Arc::new(fidl::ServeInner::new(channel)), is_terminated: false }
    }

    fn control_handle(&self) -> Self::ControlHandle {
        MainProtocolControlHandle { inner: self.inner.clone() }
    }

    fn into_inner(self) -> (::std::sync::Arc<fidl::ServeInner>, bool) {
        (self.inner, self.is_terminated)
    }

    fn from_inner(inner: std::sync::Arc<fidl::ServeInner>, is_terminated: bool) -> Self {
        Self { inner, is_terminated }
    }
}

impl futures::Stream for MainProtocolRequestStream {
    type Item = Result<MainProtocolRequest, fidl::Error>;

    fn poll_next(
        mut self: std::pin::Pin<&mut Self>,
        cx: &mut std::task::Context<'_>,
    ) -> std::task::Poll<Option<Self::Item>> {
        let this = &mut *self;
        if this.inner.poll_shutdown(cx) {
            this.is_terminated = true;
            return std::task::Poll::Ready(None);
        }
        if this.is_terminated {
            panic!("polled MainProtocolRequestStream after completion");
        }
        fidl::encoding::with_tls_decode_buf(|bytes, handles| {
            match this.inner.channel().read_etc(cx, bytes, handles) {
                std::task::Poll::Ready(Ok(())) => {}
                std::task::Poll::Pending => return std::task::Poll::Pending,
                std::task::Poll::Ready(Err(zx_status::Status::PEER_CLOSED)) => {
                    this.is_terminated = true;
                    return std::task::Poll::Ready(None);
                }
                std::task::Poll::Ready(Err(e)) => {
                    return std::task::Poll::Ready(Some(Err(fidl::Error::ServerRequestRead(e))))
                }
            }

            // A message has been received from the channel
            let (header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
            if !header.is_compatible() {
                return std::task::Poll::Ready(Some(Err(fidl::Error::IncompatibleMagicNumber(
                    header.magic_number(),
                ))));
            }

            std::task::Poll::Ready(Some(match header.ordinal() {
                0x241e4384443ccb10 => {
                    let mut req: (i32,) = fidl::encoding::Decodable::new_empty();
                    fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "test.protocolpayloads/MainProtocolOneWayComposedRequest");
                    fidl::trace_blob!("fidl:blob", "decode", bytes);
                    fidl::encoding::Decoder::decode_into(&header, _body_bytes, handles, &mut req)?;
                    fidl::duration_end!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => bytes.len() as u32, "handle_count" => handles.len() as u32);
                    let control_handle = MainProtocolControlHandle { inner: this.inner.clone() };

                    Ok(MainProtocolRequest::OneWayComposed { a: req.0, control_handle })
                }
                0x2348a1331ca4cfb0 => {
                    let mut req: (i32,) = fidl::encoding::Decodable::new_empty();
                    fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "test.protocolpayloads/MainProtocolTwoWayComposedRequest");
                    fidl::trace_blob!("fidl:blob", "decode", bytes);
                    fidl::encoding::Decoder::decode_into(&header, _body_bytes, handles, &mut req)?;
                    fidl::duration_end!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => bytes.len() as u32, "handle_count" => handles.len() as u32);
                    let control_handle = MainProtocolControlHandle { inner: this.inner.clone() };

                    Ok(MainProtocolRequest::TwoWayComposed {
                        a: req.0,
                        responder: MainProtocolTwoWayComposedResponder {
                            control_handle: std::mem::ManuallyDrop::new(control_handle),
                            tx_id: header.tx_id(),
                            ordinal: header.ordinal(),
                        },
                    })
                }
                0x6a9be48b574d1557 => {
                    let mut req: (i32,) = fidl::encoding::Decodable::new_empty();
                    fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "test.protocolpayloads/MainProtocolTwoWayComposedWithErrorRequest");
                    fidl::trace_blob!("fidl:blob", "decode", bytes);
                    fidl::encoding::Decoder::decode_into(&header, _body_bytes, handles, &mut req)?;
                    fidl::duration_end!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => bytes.len() as u32, "handle_count" => handles.len() as u32);
                    let control_handle = MainProtocolControlHandle { inner: this.inner.clone() };

                    Ok(MainProtocolRequest::TwoWayComposedWithError {
                        a: req.0,
                        responder: MainProtocolTwoWayComposedWithErrorResponder {
                            control_handle: std::mem::ManuallyDrop::new(control_handle),
                            tx_id: header.tx_id(),
                            ordinal: header.ordinal(),
                        },
                    })
                }
                0x6b9feaf9305b0715 => {
                    let mut req: (u32, u32) = fidl::encoding::Decodable::new_empty();
                    fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "test.protocolpayloads/MainProtocolOneWayLocalRequest");
                    fidl::trace_blob!("fidl:blob", "decode", bytes);
                    fidl::encoding::Decoder::decode_into(&header, _body_bytes, handles, &mut req)?;
                    fidl::duration_end!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => bytes.len() as u32, "handle_count" => handles.len() as u32);
                    let control_handle = MainProtocolControlHandle { inner: this.inner.clone() };

                    Ok(MainProtocolRequest::OneWayLocal { a: req.0, b: req.1, control_handle })
                }
                0x743776548de3af0f => {
                    let mut req: (u32, u32) = fidl::encoding::Decodable::new_empty();
                    fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "test.protocolpayloads/MainProtocolTwoWayLocalRequest");
                    fidl::trace_blob!("fidl:blob", "decode", bytes);
                    fidl::encoding::Decoder::decode_into(&header, _body_bytes, handles, &mut req)?;
                    fidl::duration_end!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => bytes.len() as u32, "handle_count" => handles.len() as u32);
                    let control_handle = MainProtocolControlHandle { inner: this.inner.clone() };

                    Ok(MainProtocolRequest::TwoWayLocal {
                        a: req.0,
                        b: req.1,
                        responder: MainProtocolTwoWayLocalResponder {
                            control_handle: std::mem::ManuallyDrop::new(control_handle),
                            tx_id: header.tx_id(),
                            ordinal: header.ordinal(),
                        },
                    })
                }
                0x2839c029915cb8fc => {
                    let mut req: (u32, u32) = fidl::encoding::Decodable::new_empty();
                    fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "test.protocolpayloads/MainProtocolTwoWayLocalWithErrorRequest");
                    fidl::trace_blob!("fidl:blob", "decode", bytes);
                    fidl::encoding::Decoder::decode_into(&header, _body_bytes, handles, &mut req)?;
                    fidl::duration_end!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => bytes.len() as u32, "handle_count" => handles.len() as u32);
                    let control_handle = MainProtocolControlHandle { inner: this.inner.clone() };

                    Ok(MainProtocolRequest::TwoWayLocalWithError {
                        a: req.0,
                        b: req.1,
                        responder: MainProtocolTwoWayLocalWithErrorResponder {
                            control_handle: std::mem::ManuallyDrop::new(control_handle),
                            tx_id: header.tx_id(),
                            ordinal: header.ordinal(),
                        },
                    })
                }
                0x2e6b091ae4cee40c => {
                    let mut req: (i32,) = fidl::encoding::Decodable::new_empty();
                    fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "test.protocolpayloads/MainProtocolOneWayImportRequest");
                    fidl::trace_blob!("fidl:blob", "decode", bytes);
                    fidl::encoding::Decoder::decode_into(&header, _body_bytes, handles, &mut req)?;
                    fidl::duration_end!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => bytes.len() as u32, "handle_count" => handles.len() as u32);
                    let control_handle = MainProtocolControlHandle { inner: this.inner.clone() };

                    Ok(MainProtocolRequest::OneWayImport { a: req.0, control_handle })
                }
                0x20f4a8f65ff69473 => {
                    let mut req: (i32,) = fidl::encoding::Decodable::new_empty();
                    fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "test.protocolpayloads/MainProtocolTwoWayImportRequest");
                    fidl::trace_blob!("fidl:blob", "decode", bytes);
                    fidl::encoding::Decoder::decode_into(&header, _body_bytes, handles, &mut req)?;
                    fidl::duration_end!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => bytes.len() as u32, "handle_count" => handles.len() as u32);
                    let control_handle = MainProtocolControlHandle { inner: this.inner.clone() };

                    Ok(MainProtocolRequest::TwoWayImport {
                        a: req.0,
                        responder: MainProtocolTwoWayImportResponder {
                            control_handle: std::mem::ManuallyDrop::new(control_handle),
                            tx_id: header.tx_id(),
                            ordinal: header.ordinal(),
                        },
                    })
                }
                0x3b7b706d42eb9bbd => {
                    let mut req: (i32,) = fidl::encoding::Decodable::new_empty();
                    fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "test.protocolpayloads/MainProtocolTwoWayImportWithErrorRequest");
                    fidl::trace_blob!("fidl:blob", "decode", bytes);
                    fidl::encoding::Decoder::decode_into(&header, _body_bytes, handles, &mut req)?;
                    fidl::duration_end!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => bytes.len() as u32, "handle_count" => handles.len() as u32);
                    let control_handle = MainProtocolControlHandle { inner: this.inner.clone() };

                    Ok(MainProtocolRequest::TwoWayImportWithError {
                        a: req.0,
                        responder: MainProtocolTwoWayImportWithErrorResponder {
                            control_handle: std::mem::ManuallyDrop::new(control_handle),
                            tx_id: header.tx_id(),
                            ordinal: header.ordinal(),
                        },
                    })
                }
                0xb43565c01ab54ac => {
                    let mut req: (u32, u32) = fidl::encoding::Decodable::new_empty();
                    fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "test.protocolpayloads/MainProtocolOneWayAnonRequest");
                    fidl::trace_blob!("fidl:blob", "decode", bytes);
                    fidl::encoding::Decoder::decode_into(&header, _body_bytes, handles, &mut req)?;
                    fidl::duration_end!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => bytes.len() as u32, "handle_count" => handles.len() as u32);
                    let control_handle = MainProtocolControlHandle { inner: this.inner.clone() };

                    Ok(MainProtocolRequest::OneWayAnon { a: req.0, b: req.1, control_handle })
                }
                0x8bdc969ff7dd759 => {
                    let mut req: (u32, u32) = fidl::encoding::Decodable::new_empty();
                    fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "test.protocolpayloads/MainProtocolTwoWayAnonRequest");
                    fidl::trace_blob!("fidl:blob", "decode", bytes);
                    fidl::encoding::Decoder::decode_into(&header, _body_bytes, handles, &mut req)?;
                    fidl::duration_end!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => bytes.len() as u32, "handle_count" => handles.len() as u32);
                    let control_handle = MainProtocolControlHandle { inner: this.inner.clone() };

                    Ok(MainProtocolRequest::TwoWayAnon {
                        a: req.0,
                        b: req.1,
                        responder: MainProtocolTwoWayAnonResponder {
                            control_handle: std::mem::ManuallyDrop::new(control_handle),
                            tx_id: header.tx_id(),
                            ordinal: header.ordinal(),
                        },
                    })
                }
                0x5862bf8170c87a36 => {
                    let mut req: (u32, u32) = fidl::encoding::Decodable::new_empty();
                    fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "test.protocolpayloads/MainProtocolTwoWayAnonWithErrorRequest");
                    fidl::trace_blob!("fidl:blob", "decode", bytes);
                    fidl::encoding::Decoder::decode_into(&header, _body_bytes, handles, &mut req)?;
                    fidl::duration_end!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => bytes.len() as u32, "handle_count" => handles.len() as u32);
                    let control_handle = MainProtocolControlHandle { inner: this.inner.clone() };

                    Ok(MainProtocolRequest::TwoWayAnonWithError {
                        a: req.0,
                        b: req.1,
                        responder: MainProtocolTwoWayAnonWithErrorResponder {
                            control_handle: std::mem::ManuallyDrop::new(control_handle),
                            tx_id: header.tx_id(),
                            ordinal: header.ordinal(),
                        },
                    })
                }
                _ => Err(fidl::Error::UnknownOrdinal {
                    ordinal: header.ordinal(),
                    protocol_name:
                        <MainProtocolMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
                }),
            }))
        })
    }
}
#[derive(Debug)]
pub enum MainProtocolRequest {
    OneWayComposed { a: i32, control_handle: MainProtocolControlHandle },
    TwoWayComposed { a: i32, responder: MainProtocolTwoWayComposedResponder },
    TwoWayComposedWithError { a: i32, responder: MainProtocolTwoWayComposedWithErrorResponder },
    OneWayLocal { a: u32, b: u32, control_handle: MainProtocolControlHandle },
    TwoWayLocal { a: u32, b: u32, responder: MainProtocolTwoWayLocalResponder },
    TwoWayLocalWithError { a: u32, b: u32, responder: MainProtocolTwoWayLocalWithErrorResponder },
    OneWayImport { a: i32, control_handle: MainProtocolControlHandle },
    TwoWayImport { a: i32, responder: MainProtocolTwoWayImportResponder },
    TwoWayImportWithError { a: i32, responder: MainProtocolTwoWayImportWithErrorResponder },
    OneWayAnon { a: u32, b: u32, control_handle: MainProtocolControlHandle },
    TwoWayAnon { a: u32, b: u32, responder: MainProtocolTwoWayAnonResponder },
    TwoWayAnonWithError { a: u32, b: u32, responder: MainProtocolTwoWayAnonWithErrorResponder },
}

impl MainProtocolRequest {
    #[allow(irrefutable_let_patterns)]
    pub fn into_one_way_composed(self) -> Option<(i32, MainProtocolControlHandle)> {
        if let MainProtocolRequest::OneWayComposed { a, control_handle } = self {
            Some((a, control_handle))
        } else {
            None
        }
    }

    #[allow(irrefutable_let_patterns)]
    pub fn into_two_way_composed(self) -> Option<(i32, MainProtocolTwoWayComposedResponder)> {
        if let MainProtocolRequest::TwoWayComposed { a, responder } = self {
            Some((a, responder))
        } else {
            None
        }
    }

    #[allow(irrefutable_let_patterns)]
    pub fn into_two_way_composed_with_error(
        self,
    ) -> Option<(i32, MainProtocolTwoWayComposedWithErrorResponder)> {
        if let MainProtocolRequest::TwoWayComposedWithError { a, responder } = self {
            Some((a, responder))
        } else {
            None
        }
    }

    #[allow(irrefutable_let_patterns)]
    pub fn into_one_way_local(self) -> Option<(u32, u32, MainProtocolControlHandle)> {
        if let MainProtocolRequest::OneWayLocal { a, b, control_handle } = self {
            Some((a, b, control_handle))
        } else {
            None
        }
    }

    #[allow(irrefutable_let_patterns)]
    pub fn into_two_way_local(self) -> Option<(u32, u32, MainProtocolTwoWayLocalResponder)> {
        if let MainProtocolRequest::TwoWayLocal { a, b, responder } = self {
            Some((a, b, responder))
        } else {
            None
        }
    }

    #[allow(irrefutable_let_patterns)]
    pub fn into_two_way_local_with_error(
        self,
    ) -> Option<(u32, u32, MainProtocolTwoWayLocalWithErrorResponder)> {
        if let MainProtocolRequest::TwoWayLocalWithError { a, b, responder } = self {
            Some((a, b, responder))
        } else {
            None
        }
    }

    #[allow(irrefutable_let_patterns)]
    pub fn into_one_way_import(self) -> Option<(i32, MainProtocolControlHandle)> {
        if let MainProtocolRequest::OneWayImport { a, control_handle } = self {
            Some((a, control_handle))
        } else {
            None
        }
    }

    #[allow(irrefutable_let_patterns)]
    pub fn into_two_way_import(self) -> Option<(i32, MainProtocolTwoWayImportResponder)> {
        if let MainProtocolRequest::TwoWayImport { a, responder } = self {
            Some((a, responder))
        } else {
            None
        }
    }

    #[allow(irrefutable_let_patterns)]
    pub fn into_two_way_import_with_error(
        self,
    ) -> Option<(i32, MainProtocolTwoWayImportWithErrorResponder)> {
        if let MainProtocolRequest::TwoWayImportWithError { a, responder } = self {
            Some((a, responder))
        } else {
            None
        }
    }

    #[allow(irrefutable_let_patterns)]
    pub fn into_one_way_anon(self) -> Option<(u32, u32, MainProtocolControlHandle)> {
        if let MainProtocolRequest::OneWayAnon { a, b, control_handle } = self {
            Some((a, b, control_handle))
        } else {
            None
        }
    }

    #[allow(irrefutable_let_patterns)]
    pub fn into_two_way_anon(self) -> Option<(u32, u32, MainProtocolTwoWayAnonResponder)> {
        if let MainProtocolRequest::TwoWayAnon { a, b, responder } = self {
            Some((a, b, responder))
        } else {
            None
        }
    }

    #[allow(irrefutable_let_patterns)]
    pub fn into_two_way_anon_with_error(
        self,
    ) -> Option<(u32, u32, MainProtocolTwoWayAnonWithErrorResponder)> {
        if let MainProtocolRequest::TwoWayAnonWithError { a, b, responder } = self {
            Some((a, b, responder))
        } else {
            None
        }
    }

    /// Name of the method defined in FIDL
    pub fn method_name(&self) -> &'static str {
        match *self {
            MainProtocolRequest::OneWayComposed { .. } => "one_way_composed",
            MainProtocolRequest::TwoWayComposed { .. } => "two_way_composed",
            MainProtocolRequest::TwoWayComposedWithError { .. } => "two_way_composed_with_error",
            MainProtocolRequest::OneWayLocal { .. } => "one_way_local",
            MainProtocolRequest::TwoWayLocal { .. } => "two_way_local",
            MainProtocolRequest::TwoWayLocalWithError { .. } => "two_way_local_with_error",
            MainProtocolRequest::OneWayImport { .. } => "one_way_import",
            MainProtocolRequest::TwoWayImport { .. } => "two_way_import",
            MainProtocolRequest::TwoWayImportWithError { .. } => "two_way_import_with_error",
            MainProtocolRequest::OneWayAnon { .. } => "one_way_anon",
            MainProtocolRequest::TwoWayAnon { .. } => "two_way_anon",
            MainProtocolRequest::TwoWayAnonWithError { .. } => "two_way_anon_with_error",
        }
    }
}

#[derive(Debug, Clone)]
pub struct MainProtocolControlHandle {
    inner: std::sync::Arc<fidl::ServeInner>,
}

impl fidl::endpoints::ControlHandle for MainProtocolControlHandle {
    fn shutdown(&self) {
        self.inner.shutdown()
    }

    fn shutdown_with_epitaph(&self, status: zx_status::Status) {
        self.inner.shutdown_with_epitaph(status)
    }
}

impl MainProtocolControlHandle {
    pub fn send_on_composed(&self, mut a: i32) -> Result<(), fidl::Error> {
        let mut response = (a);

        let mut msg = fidl::encoding::TransactionMessage {
            header: fidl::encoding::TransactionHeader::new(
                0,
                0x19fbe2b2f6f9273a,
                fidl::encoding::DynamicFlags::empty(),
            ),
            body: &mut response,
        };

        fidl::encoding::with_tls_encoded(&mut msg, |bytes, handles| {
            self.inner
                .channel()
                .write_etc(&*bytes, &mut *handles)
                .map_err(fidl::Error::ServerResponseWrite)
        })?;

        Ok(())
    }

    pub fn send_on_composed_with_error(
        &self,
        mut result: &mut fidl_test_protocolpayloads_imported::ComposedProtocolOnComposedWithErrorResult,
    ) -> Result<(), fidl::Error> {
        let mut response = (result);

        let mut msg = fidl::encoding::TransactionMessage {
            header: fidl::encoding::TransactionHeader::new(
                0,
                0x63774db677215e98,
                fidl::encoding::DynamicFlags::empty(),
            ),
            body: &mut response,
        };

        fidl::encoding::with_tls_encoded(&mut msg, |bytes, handles| {
            self.inner
                .channel()
                .write_etc(&*bytes, &mut *handles)
                .map_err(fidl::Error::ServerResponseWrite)
        })?;

        Ok(())
    }

    pub fn send_on_local(&self, mut a: u32, mut b: u32) -> Result<(), fidl::Error> {
        let mut response = (a, b);

        let mut msg = fidl::encoding::TransactionMessage {
            header: fidl::encoding::TransactionHeader::new(
                0,
                0x4745f7438cd80819,
                fidl::encoding::DynamicFlags::empty(),
            ),
            body: &mut response,
        };

        fidl::encoding::with_tls_encoded(&mut msg, |bytes, handles| {
            self.inner
                .channel()
                .write_etc(&*bytes, &mut *handles)
                .map_err(fidl::Error::ServerResponseWrite)
        })?;

        Ok(())
    }

    pub fn send_on_local_with_error(
        &self,
        mut result: &mut MainProtocolOnLocalWithErrorResult,
    ) -> Result<(), fidl::Error> {
        let mut response = (result);

        let mut msg = fidl::encoding::TransactionMessage {
            header: fidl::encoding::TransactionHeader::new(
                0,
                0x4ecd4b3982e221af,
                fidl::encoding::DynamicFlags::empty(),
            ),
            body: &mut response,
        };

        fidl::encoding::with_tls_encoded(&mut msg, |bytes, handles| {
            self.inner
                .channel()
                .write_etc(&*bytes, &mut *handles)
                .map_err(fidl::Error::ServerResponseWrite)
        })?;

        Ok(())
    }

    pub fn send_on_import(&self, mut a: i32) -> Result<(), fidl::Error> {
        let mut response = (a);

        let mut msg = fidl::encoding::TransactionMessage {
            header: fidl::encoding::TransactionHeader::new(
                0,
                0x1bb4f4c30b6f8909,
                fidl::encoding::DynamicFlags::empty(),
            ),
            body: &mut response,
        };

        fidl::encoding::with_tls_encoded(&mut msg, |bytes, handles| {
            self.inner
                .channel()
                .write_etc(&*bytes, &mut *handles)
                .map_err(fidl::Error::ServerResponseWrite)
        })?;

        Ok(())
    }

    pub fn send_on_import_with_error(
        &self,
        mut result: &mut MainProtocolOnImportWithErrorResult,
    ) -> Result<(), fidl::Error> {
        let mut response = (result);

        let mut msg = fidl::encoding::TransactionMessage {
            header: fidl::encoding::TransactionHeader::new(
                0,
                0x6292b793d728f205,
                fidl::encoding::DynamicFlags::empty(),
            ),
            body: &mut response,
        };

        fidl::encoding::with_tls_encoded(&mut msg, |bytes, handles| {
            self.inner
                .channel()
                .write_etc(&*bytes, &mut *handles)
                .map_err(fidl::Error::ServerResponseWrite)
        })?;

        Ok(())
    }

    pub fn send_on_anon(&self, mut a: u32, mut b: u32) -> Result<(), fidl::Error> {
        let mut response = (a, b);

        let mut msg = fidl::encoding::TransactionMessage {
            header: fidl::encoding::TransactionHeader::new(
                0,
                0x42d321dacc4df000,
                fidl::encoding::DynamicFlags::empty(),
            ),
            body: &mut response,
        };

        fidl::encoding::with_tls_encoded(&mut msg, |bytes, handles| {
            self.inner
                .channel()
                .write_etc(&*bytes, &mut *handles)
                .map_err(fidl::Error::ServerResponseWrite)
        })?;

        Ok(())
    }

    pub fn send_on_anon_with_error(
        &self,
        mut result: &mut MainProtocolOnAnonWithErrorResult,
    ) -> Result<(), fidl::Error> {
        let mut response = (result);

        let mut msg = fidl::encoding::TransactionMessage {
            header: fidl::encoding::TransactionHeader::new(
                0,
                0x45bc24ef47b44a02,
                fidl::encoding::DynamicFlags::empty(),
            ),
            body: &mut response,
        };

        fidl::encoding::with_tls_encoded(&mut msg, |bytes, handles| {
            self.inner
                .channel()
                .write_etc(&*bytes, &mut *handles)
                .map_err(fidl::Error::ServerResponseWrite)
        })?;

        Ok(())
    }
}
#[must_use = "FIDL methods require a response to be sent"]
#[derive(Debug)]
pub struct MainProtocolTwoWayComposedResponder {
    control_handle: std::mem::ManuallyDrop<MainProtocolControlHandle>,
    tx_id: u32,
    ordinal: u64,
}

/// Set the the channel to be shutdown (see [`MainProtocolControlHandle::shutdown`])
/// if the responder is dropped without sending a response, so that the client
/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
impl std::ops::Drop for MainProtocolTwoWayComposedResponder {
    fn drop(&mut self) {
        self.control_handle.shutdown();
        // Safety: drops once, never accessed again
        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
    }
}

impl fidl::endpoints::Responder for MainProtocolTwoWayComposedResponder {
    type ControlHandle = MainProtocolControlHandle;

    fn control_handle(&self) -> &MainProtocolControlHandle {
        &self.control_handle
    }

    fn drop_without_shutdown(mut self) {
        // Safety: drops once, never accessed again due to mem::forget
        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
        // Prevent Drop from running (which would shut down the channel)
        std::mem::forget(self);
    }
}

impl MainProtocolTwoWayComposedResponder {
    /// Sends a response to the FIDL transaction.
    ///
    /// Sets the channel to shutdown if an error occurs.
    pub fn send(self, mut a: i32) -> Result<(), fidl::Error> {
        let r = self.send_raw(a);
        if r.is_err() {
            self.control_handle.shutdown();
        }
        self.drop_without_shutdown();
        r
    }

    /// Similar to "send" but does not shutdown the channel if
    /// an error occurs.
    pub fn send_no_shutdown_on_err(self, mut a: i32) -> Result<(), fidl::Error> {
        let r = self.send_raw(a);
        self.drop_without_shutdown();
        r
    }

    fn send_raw(&self, mut a: i32) -> Result<(), fidl::Error> {
        let mut response = (a);

        let mut msg = fidl::encoding::TransactionMessage {
            header: fidl::encoding::TransactionHeader::new(
                self.tx_id,
                self.ordinal,
                fidl::encoding::DynamicFlags::empty(),
            ),
            body: &mut response,
        };

        fidl::encoding::with_tls_encode_buf(|bytes, handles| {
            fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "test.protocolpayloads/MainProtocolTwoWayComposedResponse");
            fidl::encoding::Encoder::encode(bytes, handles, &mut msg)?;
            fidl::trace_blob!("fidl:blob", "encode", bytes.as_slice());
            fidl::duration_end!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => bytes.len() as u32, "handle_count" => handles.len() as u32);

            self.control_handle
                .inner
                .channel()
                .write_etc(&*bytes, &mut *handles)
                .map_err(fidl::Error::ServerResponseWrite)?;
            Ok(())
        })
    }
}
#[must_use = "FIDL methods require a response to be sent"]
#[derive(Debug)]
pub struct MainProtocolTwoWayComposedWithErrorResponder {
    control_handle: std::mem::ManuallyDrop<MainProtocolControlHandle>,
    tx_id: u32,
    ordinal: u64,
}

/// Set the the channel to be shutdown (see [`MainProtocolControlHandle::shutdown`])
/// if the responder is dropped without sending a response, so that the client
/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
impl std::ops::Drop for MainProtocolTwoWayComposedWithErrorResponder {
    fn drop(&mut self) {
        self.control_handle.shutdown();
        // Safety: drops once, never accessed again
        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
    }
}

impl fidl::endpoints::Responder for MainProtocolTwoWayComposedWithErrorResponder {
    type ControlHandle = MainProtocolControlHandle;

    fn control_handle(&self) -> &MainProtocolControlHandle {
        &self.control_handle
    }

    fn drop_without_shutdown(mut self) {
        // Safety: drops once, never accessed again due to mem::forget
        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
        // Prevent Drop from running (which would shut down the channel)
        std::mem::forget(self);
    }
}

impl MainProtocolTwoWayComposedWithErrorResponder {
    /// Sends a response to the FIDL transaction.
    ///
    /// Sets the channel to shutdown if an error occurs.
    pub fn send(
        self,
        mut result: &mut fidl_test_protocolpayloads_imported::ComposedProtocolTwoWayComposedWithErrorResult,
    ) -> Result<(), fidl::Error> {
        let r = self.send_raw(result);
        if r.is_err() {
            self.control_handle.shutdown();
        }
        self.drop_without_shutdown();
        r
    }

    /// Similar to "send" but does not shutdown the channel if
    /// an error occurs.
    pub fn send_no_shutdown_on_err(
        self,
        mut result: &mut fidl_test_protocolpayloads_imported::ComposedProtocolTwoWayComposedWithErrorResult,
    ) -> Result<(), fidl::Error> {
        let r = self.send_raw(result);
        self.drop_without_shutdown();
        r
    }

    fn send_raw(
        &self,
        mut _result: &mut fidl_test_protocolpayloads_imported::ComposedProtocolTwoWayComposedWithErrorResult,
    ) -> Result<(), fidl::Error> {
        let mut response = (_result);

        let mut msg = fidl::encoding::TransactionMessage {
            header: fidl::encoding::TransactionHeader::new(
                self.tx_id,
                self.ordinal,
                fidl::encoding::DynamicFlags::empty(),
            ),
            body: &mut response,
        };

        fidl::encoding::with_tls_encode_buf(|bytes, handles| {
            fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "test.protocolpayloads/MainProtocolTwoWayComposedWithErrorResponse");
            fidl::encoding::Encoder::encode(bytes, handles, &mut msg)?;
            fidl::trace_blob!("fidl:blob", "encode", bytes.as_slice());
            fidl::duration_end!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => bytes.len() as u32, "handle_count" => handles.len() as u32);

            self.control_handle
                .inner
                .channel()
                .write_etc(&*bytes, &mut *handles)
                .map_err(fidl::Error::ServerResponseWrite)?;
            Ok(())
        })
    }
}
#[must_use = "FIDL methods require a response to be sent"]
#[derive(Debug)]
pub struct MainProtocolTwoWayLocalResponder {
    control_handle: std::mem::ManuallyDrop<MainProtocolControlHandle>,
    tx_id: u32,
    ordinal: u64,
}

/// Set the the channel to be shutdown (see [`MainProtocolControlHandle::shutdown`])
/// if the responder is dropped without sending a response, so that the client
/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
impl std::ops::Drop for MainProtocolTwoWayLocalResponder {
    fn drop(&mut self) {
        self.control_handle.shutdown();
        // Safety: drops once, never accessed again
        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
    }
}

impl fidl::endpoints::Responder for MainProtocolTwoWayLocalResponder {
    type ControlHandle = MainProtocolControlHandle;

    fn control_handle(&self) -> &MainProtocolControlHandle {
        &self.control_handle
    }

    fn drop_without_shutdown(mut self) {
        // Safety: drops once, never accessed again due to mem::forget
        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
        // Prevent Drop from running (which would shut down the channel)
        std::mem::forget(self);
    }
}

impl MainProtocolTwoWayLocalResponder {
    /// Sends a response to the FIDL transaction.
    ///
    /// Sets the channel to shutdown if an error occurs.
    pub fn send(self, mut a: u32, mut b: u32) -> Result<(), fidl::Error> {
        let r = self.send_raw(a, b);
        if r.is_err() {
            self.control_handle.shutdown();
        }
        self.drop_without_shutdown();
        r
    }

    /// Similar to "send" but does not shutdown the channel if
    /// an error occurs.
    pub fn send_no_shutdown_on_err(self, mut a: u32, mut b: u32) -> Result<(), fidl::Error> {
        let r = self.send_raw(a, b);
        self.drop_without_shutdown();
        r
    }

    fn send_raw(&self, mut a: u32, mut b: u32) -> Result<(), fidl::Error> {
        let mut response = ((a, b));

        let mut msg = fidl::encoding::TransactionMessage {
            header: fidl::encoding::TransactionHeader::new(
                self.tx_id,
                self.ordinal,
                fidl::encoding::DynamicFlags::empty(),
            ),
            body: &mut response,
        };

        fidl::encoding::with_tls_encode_buf(|bytes, handles| {
            fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "test.protocolpayloads/MainProtocolTwoWayLocalResponse");
            fidl::encoding::Encoder::encode(bytes, handles, &mut msg)?;
            fidl::trace_blob!("fidl:blob", "encode", bytes.as_slice());
            fidl::duration_end!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => bytes.len() as u32, "handle_count" => handles.len() as u32);

            self.control_handle
                .inner
                .channel()
                .write_etc(&*bytes, &mut *handles)
                .map_err(fidl::Error::ServerResponseWrite)?;
            Ok(())
        })
    }
}
#[must_use = "FIDL methods require a response to be sent"]
#[derive(Debug)]
pub struct MainProtocolTwoWayLocalWithErrorResponder {
    control_handle: std::mem::ManuallyDrop<MainProtocolControlHandle>,
    tx_id: u32,
    ordinal: u64,
}

/// Set the the channel to be shutdown (see [`MainProtocolControlHandle::shutdown`])
/// if the responder is dropped without sending a response, so that the client
/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
impl std::ops::Drop for MainProtocolTwoWayLocalWithErrorResponder {
    fn drop(&mut self) {
        self.control_handle.shutdown();
        // Safety: drops once, never accessed again
        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
    }
}

impl fidl::endpoints::Responder for MainProtocolTwoWayLocalWithErrorResponder {
    type ControlHandle = MainProtocolControlHandle;

    fn control_handle(&self) -> &MainProtocolControlHandle {
        &self.control_handle
    }

    fn drop_without_shutdown(mut self) {
        // Safety: drops once, never accessed again due to mem::forget
        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
        // Prevent Drop from running (which would shut down the channel)
        std::mem::forget(self);
    }
}

impl MainProtocolTwoWayLocalWithErrorResponder {
    /// Sends a response to the FIDL transaction.
    ///
    /// Sets the channel to shutdown if an error occurs.
    pub fn send(
        self,
        mut result: &mut MainProtocolTwoWayLocalWithErrorResult,
    ) -> Result<(), fidl::Error> {
        let r = self.send_raw(result);
        if r.is_err() {
            self.control_handle.shutdown();
        }
        self.drop_without_shutdown();
        r
    }

    /// Similar to "send" but does not shutdown the channel if
    /// an error occurs.
    pub fn send_no_shutdown_on_err(
        self,
        mut result: &mut MainProtocolTwoWayLocalWithErrorResult,
    ) -> Result<(), fidl::Error> {
        let r = self.send_raw(result);
        self.drop_without_shutdown();
        r
    }

    fn send_raw(
        &self,
        mut _result: &mut MainProtocolTwoWayLocalWithErrorResult,
    ) -> Result<(), fidl::Error> {
        let mut response = (_result);

        let mut msg = fidl::encoding::TransactionMessage {
            header: fidl::encoding::TransactionHeader::new(
                self.tx_id,
                self.ordinal,
                fidl::encoding::DynamicFlags::empty(),
            ),
            body: &mut response,
        };

        fidl::encoding::with_tls_encode_buf(|bytes, handles| {
            fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "test.protocolpayloads/MainProtocolTwoWayLocalWithErrorResponse");
            fidl::encoding::Encoder::encode(bytes, handles, &mut msg)?;
            fidl::trace_blob!("fidl:blob", "encode", bytes.as_slice());
            fidl::duration_end!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => bytes.len() as u32, "handle_count" => handles.len() as u32);

            self.control_handle
                .inner
                .channel()
                .write_etc(&*bytes, &mut *handles)
                .map_err(fidl::Error::ServerResponseWrite)?;
            Ok(())
        })
    }
}
#[must_use = "FIDL methods require a response to be sent"]
#[derive(Debug)]
pub struct MainProtocolTwoWayImportResponder {
    control_handle: std::mem::ManuallyDrop<MainProtocolControlHandle>,
    tx_id: u32,
    ordinal: u64,
}

/// Set the the channel to be shutdown (see [`MainProtocolControlHandle::shutdown`])
/// if the responder is dropped without sending a response, so that the client
/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
impl std::ops::Drop for MainProtocolTwoWayImportResponder {
    fn drop(&mut self) {
        self.control_handle.shutdown();
        // Safety: drops once, never accessed again
        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
    }
}

impl fidl::endpoints::Responder for MainProtocolTwoWayImportResponder {
    type ControlHandle = MainProtocolControlHandle;

    fn control_handle(&self) -> &MainProtocolControlHandle {
        &self.control_handle
    }

    fn drop_without_shutdown(mut self) {
        // Safety: drops once, never accessed again due to mem::forget
        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
        // Prevent Drop from running (which would shut down the channel)
        std::mem::forget(self);
    }
}

impl MainProtocolTwoWayImportResponder {
    /// Sends a response to the FIDL transaction.
    ///
    /// Sets the channel to shutdown if an error occurs.
    pub fn send(self, mut a: i32) -> Result<(), fidl::Error> {
        let r = self.send_raw(a);
        if r.is_err() {
            self.control_handle.shutdown();
        }
        self.drop_without_shutdown();
        r
    }

    /// Similar to "send" but does not shutdown the channel if
    /// an error occurs.
    pub fn send_no_shutdown_on_err(self, mut a: i32) -> Result<(), fidl::Error> {
        let r = self.send_raw(a);
        self.drop_without_shutdown();
        r
    }

    fn send_raw(&self, mut a: i32) -> Result<(), fidl::Error> {
        let mut response = (a);

        let mut msg = fidl::encoding::TransactionMessage {
            header: fidl::encoding::TransactionHeader::new(
                self.tx_id,
                self.ordinal,
                fidl::encoding::DynamicFlags::empty(),
            ),
            body: &mut response,
        };

        fidl::encoding::with_tls_encode_buf(|bytes, handles| {
            fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "test.protocolpayloads/MainProtocolTwoWayImportResponse");
            fidl::encoding::Encoder::encode(bytes, handles, &mut msg)?;
            fidl::trace_blob!("fidl:blob", "encode", bytes.as_slice());
            fidl::duration_end!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => bytes.len() as u32, "handle_count" => handles.len() as u32);

            self.control_handle
                .inner
                .channel()
                .write_etc(&*bytes, &mut *handles)
                .map_err(fidl::Error::ServerResponseWrite)?;
            Ok(())
        })
    }
}
#[must_use = "FIDL methods require a response to be sent"]
#[derive(Debug)]
pub struct MainProtocolTwoWayImportWithErrorResponder {
    control_handle: std::mem::ManuallyDrop<MainProtocolControlHandle>,
    tx_id: u32,
    ordinal: u64,
}

/// Set the the channel to be shutdown (see [`MainProtocolControlHandle::shutdown`])
/// if the responder is dropped without sending a response, so that the client
/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
impl std::ops::Drop for MainProtocolTwoWayImportWithErrorResponder {
    fn drop(&mut self) {
        self.control_handle.shutdown();
        // Safety: drops once, never accessed again
        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
    }
}

impl fidl::endpoints::Responder for MainProtocolTwoWayImportWithErrorResponder {
    type ControlHandle = MainProtocolControlHandle;

    fn control_handle(&self) -> &MainProtocolControlHandle {
        &self.control_handle
    }

    fn drop_without_shutdown(mut self) {
        // Safety: drops once, never accessed again due to mem::forget
        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
        // Prevent Drop from running (which would shut down the channel)
        std::mem::forget(self);
    }
}

impl MainProtocolTwoWayImportWithErrorResponder {
    /// Sends a response to the FIDL transaction.
    ///
    /// Sets the channel to shutdown if an error occurs.
    pub fn send(
        self,
        mut result: &mut MainProtocolTwoWayImportWithErrorResult,
    ) -> Result<(), fidl::Error> {
        let r = self.send_raw(result);
        if r.is_err() {
            self.control_handle.shutdown();
        }
        self.drop_without_shutdown();
        r
    }

    /// Similar to "send" but does not shutdown the channel if
    /// an error occurs.
    pub fn send_no_shutdown_on_err(
        self,
        mut result: &mut MainProtocolTwoWayImportWithErrorResult,
    ) -> Result<(), fidl::Error> {
        let r = self.send_raw(result);
        self.drop_without_shutdown();
        r
    }

    fn send_raw(
        &self,
        mut _result: &mut MainProtocolTwoWayImportWithErrorResult,
    ) -> Result<(), fidl::Error> {
        let mut response = (_result);

        let mut msg = fidl::encoding::TransactionMessage {
            header: fidl::encoding::TransactionHeader::new(
                self.tx_id,
                self.ordinal,
                fidl::encoding::DynamicFlags::empty(),
            ),
            body: &mut response,
        };

        fidl::encoding::with_tls_encode_buf(|bytes, handles| {
            fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "test.protocolpayloads/MainProtocolTwoWayImportWithErrorResponse");
            fidl::encoding::Encoder::encode(bytes, handles, &mut msg)?;
            fidl::trace_blob!("fidl:blob", "encode", bytes.as_slice());
            fidl::duration_end!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => bytes.len() as u32, "handle_count" => handles.len() as u32);

            self.control_handle
                .inner
                .channel()
                .write_etc(&*bytes, &mut *handles)
                .map_err(fidl::Error::ServerResponseWrite)?;
            Ok(())
        })
    }
}
#[must_use = "FIDL methods require a response to be sent"]
#[derive(Debug)]
pub struct MainProtocolTwoWayAnonResponder {
    control_handle: std::mem::ManuallyDrop<MainProtocolControlHandle>,
    tx_id: u32,
    ordinal: u64,
}

/// Set the the channel to be shutdown (see [`MainProtocolControlHandle::shutdown`])
/// if the responder is dropped without sending a response, so that the client
/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
impl std::ops::Drop for MainProtocolTwoWayAnonResponder {
    fn drop(&mut self) {
        self.control_handle.shutdown();
        // Safety: drops once, never accessed again
        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
    }
}

impl fidl::endpoints::Responder for MainProtocolTwoWayAnonResponder {
    type ControlHandle = MainProtocolControlHandle;

    fn control_handle(&self) -> &MainProtocolControlHandle {
        &self.control_handle
    }

    fn drop_without_shutdown(mut self) {
        // Safety: drops once, never accessed again due to mem::forget
        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
        // Prevent Drop from running (which would shut down the channel)
        std::mem::forget(self);
    }
}

impl MainProtocolTwoWayAnonResponder {
    /// Sends a response to the FIDL transaction.
    ///
    /// Sets the channel to shutdown if an error occurs.
    pub fn send(self, mut a: u32, mut b: u32) -> Result<(), fidl::Error> {
        let r = self.send_raw(a, b);
        if r.is_err() {
            self.control_handle.shutdown();
        }
        self.drop_without_shutdown();
        r
    }

    /// Similar to "send" but does not shutdown the channel if
    /// an error occurs.
    pub fn send_no_shutdown_on_err(self, mut a: u32, mut b: u32) -> Result<(), fidl::Error> {
        let r = self.send_raw(a, b);
        self.drop_without_shutdown();
        r
    }

    fn send_raw(&self, mut a: u32, mut b: u32) -> Result<(), fidl::Error> {
        let mut response = ((a, b));

        let mut msg = fidl::encoding::TransactionMessage {
            header: fidl::encoding::TransactionHeader::new(
                self.tx_id,
                self.ordinal,
                fidl::encoding::DynamicFlags::empty(),
            ),
            body: &mut response,
        };

        fidl::encoding::with_tls_encode_buf(|bytes, handles| {
            fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "test.protocolpayloads/MainProtocolTwoWayAnonResponse");
            fidl::encoding::Encoder::encode(bytes, handles, &mut msg)?;
            fidl::trace_blob!("fidl:blob", "encode", bytes.as_slice());
            fidl::duration_end!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => bytes.len() as u32, "handle_count" => handles.len() as u32);

            self.control_handle
                .inner
                .channel()
                .write_etc(&*bytes, &mut *handles)
                .map_err(fidl::Error::ServerResponseWrite)?;
            Ok(())
        })
    }
}
#[must_use = "FIDL methods require a response to be sent"]
#[derive(Debug)]
pub struct MainProtocolTwoWayAnonWithErrorResponder {
    control_handle: std::mem::ManuallyDrop<MainProtocolControlHandle>,
    tx_id: u32,
    ordinal: u64,
}

/// Set the the channel to be shutdown (see [`MainProtocolControlHandle::shutdown`])
/// if the responder is dropped without sending a response, so that the client
/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
impl std::ops::Drop for MainProtocolTwoWayAnonWithErrorResponder {
    fn drop(&mut self) {
        self.control_handle.shutdown();
        // Safety: drops once, never accessed again
        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
    }
}

impl fidl::endpoints::Responder for MainProtocolTwoWayAnonWithErrorResponder {
    type ControlHandle = MainProtocolControlHandle;

    fn control_handle(&self) -> &MainProtocolControlHandle {
        &self.control_handle
    }

    fn drop_without_shutdown(mut self) {
        // Safety: drops once, never accessed again due to mem::forget
        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
        // Prevent Drop from running (which would shut down the channel)
        std::mem::forget(self);
    }
}

impl MainProtocolTwoWayAnonWithErrorResponder {
    /// Sends a response to the FIDL transaction.
    ///
    /// Sets the channel to shutdown if an error occurs.
    pub fn send(
        self,
        mut result: &mut MainProtocolTwoWayAnonWithErrorResult,
    ) -> Result<(), fidl::Error> {
        let r = self.send_raw(result);
        if r.is_err() {
            self.control_handle.shutdown();
        }
        self.drop_without_shutdown();
        r
    }

    /// Similar to "send" but does not shutdown the channel if
    /// an error occurs.
    pub fn send_no_shutdown_on_err(
        self,
        mut result: &mut MainProtocolTwoWayAnonWithErrorResult,
    ) -> Result<(), fidl::Error> {
        let r = self.send_raw(result);
        self.drop_without_shutdown();
        r
    }

    fn send_raw(
        &self,
        mut _result: &mut MainProtocolTwoWayAnonWithErrorResult,
    ) -> Result<(), fidl::Error> {
        let mut response = (_result);

        let mut msg = fidl::encoding::TransactionMessage {
            header: fidl::encoding::TransactionHeader::new(
                self.tx_id,
                self.ordinal,
                fidl::encoding::DynamicFlags::empty(),
            ),
            body: &mut response,
        };

        fidl::encoding::with_tls_encode_buf(|bytes, handles| {
            fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "test.protocolpayloads/MainProtocolTwoWayAnonWithErrorResponse");
            fidl::encoding::Encoder::encode(bytes, handles, &mut msg)?;
            fidl::trace_blob!("fidl:blob", "encode", bytes.as_slice());
            fidl::duration_end!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => bytes.len() as u32, "handle_count" => handles.len() as u32);

            self.control_handle
                .inner
                .channel()
                .write_etc(&*bytes, &mut *handles)
                .map_err(fidl::Error::ServerResponseWrite)?;
            Ok(())
        })
    }
}
