// 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 _},
        fidl_empty_struct, fidl_flexible_bits, fidl_flexible_enum, fidl_strict_bits,
        fidl_strict_enum, fidl_struct, fidl_struct_copy, fidl_table, fidl_xunion,
        wrap_handle_metadata,
    },
    fuchsia_zircon_status as zx_status,
    futures::future::{self, MaybeDone, TryFutureExt},
};

const _FIDL_TRACE_BINDINGS_RUST: u32 = 6;

#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
#[repr(u32)]
pub enum ObjType {
    None = 0,
    Socket = 14,
}
fidl_strict_enum! {
    name: ObjType,
    prim_ty: u32,
    members: [
        None { value: 0, },
        Socket { value: 14, },
    ],
}

#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
#[repr(u32)]
pub enum ErrorEnun {
    ErrFoo = 1,
    ErrBar = 2,
}
fidl_strict_enum! {
    name: ErrorEnun,
    prim_ty: u32,
    members: [
        ErrFoo { value: 1, },
        ErrBar { value: 2, },
    ],
}

pub type WithErrorSyntaxResponseAsStructResult = std::result::Result<(i64, i64, i64), u32>;

pub type WithErrorSyntaxResponseAsStructResultHandleWrapper =
    std::result::Result<(i64, i64, i64), u32>;

pub type WithErrorSyntaxErrorAsPrimitiveResult = std::result::Result<(), u32>;

pub type WithErrorSyntaxErrorAsPrimitiveResultHandleWrapper = std::result::Result<(), u32>;

pub type WithErrorSyntaxErrorAsEnumResult = std::result::Result<(), ErrorEnun>;

pub type WithErrorSyntaxErrorAsEnumResultHandleWrapper = std::result::Result<(), ErrorEnun>;

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

fidl_struct_copy! {
  name: WithErrorSyntaxResponseAsStructResponse,
  members: [
    a {
      ty: i64,
      offset_v1: 0,
    },
    b {
      ty: i64,
      offset_v1: 8,
    },
    c {
      ty: i64,
      offset_v1: 16,
    },
  ],
  padding: [],
  size_v1: 24,
  align_v1: 8,
}

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

fidl_empty_struct!(WithErrorSyntaxErrorAsPrimitiveResponse);

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

fidl_empty_struct!(WithErrorSyntaxErrorAsEnumResponse);
wrap_handle_metadata!(
    HandleWrapperObjectTypeNONERights2147483648,
    fidl::ObjectType::NONE,
    fidl::Rights::from_bits_const(2147483648).unwrap()
);

wrap_handle_metadata!(
    HandleWrapperObjectTypeSOCKETRights2147483648,
    fidl::ObjectType::SOCKET,
    fidl::Rights::from_bits_const(2147483648).unwrap()
);

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

impl fidl::endpoints::ServiceMarker for WithAndWithoutRequestResponseMarker {
    type Proxy = WithAndWithoutRequestResponseProxy;
    type RequestStream = WithAndWithoutRequestResponseRequestStream;
    const DEBUG_NAME: &'static str = "(anonymous) WithAndWithoutRequestResponse";
}

pub trait WithAndWithoutRequestResponseProxyInterface: Send + Sync {
    fn r#no_request_no_response(&self) -> Result<(), fidl::Error>;
    type NoRequestEmptyResponseResponseFut: std::future::Future<Output = Result<(), fidl::Error>>
        + Send;
    fn r#no_request_empty_response(&self) -> Self::NoRequestEmptyResponseResponseFut;
    type NoRequestWithResponseResponseFut: std::future::Future<Output = Result<(String), fidl::Error>>
        + Send;
    fn r#no_request_with_response(&self) -> Self::NoRequestWithResponseResponseFut;
    fn r#with_request_no_response(&self, arg: &str) -> Result<(), fidl::Error>;
    type WithRequestEmptyResponseResponseFut: std::future::Future<Output = Result<(), fidl::Error>>
        + Send;
    fn r#with_request_empty_response(&self, arg: &str)
        -> Self::WithRequestEmptyResponseResponseFut;
    type WithRequestWithResponseResponseFut: std::future::Future<Output = Result<(String), fidl::Error>>
        + Send;
    fn r#with_request_with_response(&self, arg: &str) -> Self::WithRequestWithResponseResponseFut;
    type OnEmptyResponseResponseFut: std::future::Future<Output = Result<(), fidl::Error>> + Send;
    type OnWithResponseResponseFut: std::future::Future<Output = Result<(String), fidl::Error>>
        + Send;
}

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

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

    pub fn into_channel(self) -> fidl::Channel {
        self.client.into_channel()
    }
    pub fn r#no_request_no_response(&mut self) -> Result<(), fidl::Error> {
        self.client.send(&mut (), 0x6ad894147d0c6ba4)
    }
    pub fn r#no_request_empty_response(
        &mut self,
        ___deadline: zx::Time,
    ) -> Result<(), fidl::Error> {
        let _value: () = self.client.send_query(&mut (), 0x4068f26bf6d868ae, ___deadline)?;
        Ok(())
    }
    pub fn r#no_request_with_response(
        &mut self,
        ___deadline: zx::Time,
    ) -> Result<(String), fidl::Error> {
        let _value: (String,) = self.client.send_query(&mut (), 0x447e655905ccfbf4, ___deadline)?;
        Ok(_value.0)
    }
    pub fn r#with_request_no_response(&mut self, mut arg: &str) -> Result<(), fidl::Error> {
        self.client.send(&mut (arg), 0x7cb47b2f9e76d17d)
    }
    pub fn r#with_request_empty_response(
        &mut self,
        mut arg: &str,
        ___deadline: zx::Time,
    ) -> Result<(), fidl::Error> {
        let _value: () = self.client.send_query(&mut (arg), 0x65eb512ff0e1c07e, ___deadline)?;
        Ok(())
    }
    pub fn r#with_request_with_response(
        &mut self,
        mut arg: &str,
        ___deadline: zx::Time,
    ) -> Result<(String), fidl::Error> {
        let _value: (String,) =
            self.client.send_query(&mut (arg), 0x1d323510d4447cf1, ___deadline)?;
        Ok(_value.0)
    }
}

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

impl fidl::endpoints::Proxy for WithAndWithoutRequestResponseProxy {
    type Service = WithAndWithoutRequestResponseMarker;

    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 WithAndWithoutRequestResponseProxy {
    /// Create a new Proxy for WithAndWithoutRequestResponse
    pub fn new(channel: fidl::AsyncChannel) -> Self {
        let service_name =
            <WithAndWithoutRequestResponseMarker as fidl::endpoints::ServiceMarker>::DEBUG_NAME;
        Self { client: fidl::client::Client::new(channel, service_name) }
    }

    /// Get a Stream of events from the remote end of the WithAndWithoutRequestResponse protocol
    ///
    /// # Panics
    ///
    /// Panics if the event stream was already taken.
    pub fn take_event_stream(&self) -> WithAndWithoutRequestResponseEventStream {
        WithAndWithoutRequestResponseEventStream {
            event_receiver: self.client.take_event_receiver(),
        }
    }
    pub fn r#no_request_no_response(&self) -> Result<(), fidl::Error> {
        WithAndWithoutRequestResponseProxyInterface::r#no_request_no_response(self)
    }
    pub fn r#no_request_empty_response(&self) -> fidl::client::QueryResponseFut<()> {
        WithAndWithoutRequestResponseProxyInterface::r#no_request_empty_response(self)
    }
    pub fn r#no_request_with_response(&self) -> fidl::client::QueryResponseFut<(String)> {
        WithAndWithoutRequestResponseProxyInterface::r#no_request_with_response(self)
    }
    pub fn r#with_request_no_response(&self, mut arg: &str) -> Result<(), fidl::Error> {
        WithAndWithoutRequestResponseProxyInterface::r#with_request_no_response(self, arg)
    }
    pub fn r#with_request_empty_response(
        &self,
        mut arg: &str,
    ) -> fidl::client::QueryResponseFut<()> {
        WithAndWithoutRequestResponseProxyInterface::r#with_request_empty_response(self, arg)
    }
    pub fn r#with_request_with_response(
        &self,
        mut arg: &str,
    ) -> fidl::client::QueryResponseFut<(String)> {
        WithAndWithoutRequestResponseProxyInterface::r#with_request_with_response(self, arg)
    }
}

impl WithAndWithoutRequestResponseProxyInterface for WithAndWithoutRequestResponseProxy {
    fn r#no_request_no_response(&self) -> Result<(), fidl::Error> {
        self.client.send(&mut (), 0x6ad894147d0c6ba4)
    }
    type NoRequestEmptyResponseResponseFut = fidl::client::QueryResponseFut<()>;
    fn r#no_request_empty_response(&self) -> Self::NoRequestEmptyResponseResponseFut {
        fn transform(result: Result<(), fidl::Error>) -> Result<(), fidl::Error> {
            result.map(|_value| ())
        }
        let send_result = self.client.call_send_raw_query(&mut (), 0x4068f26bf6d868ae);
        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 NoRequestWithResponseResponseFut = fidl::client::QueryResponseFut<(String)>;
    fn r#no_request_with_response(&self) -> Self::NoRequestWithResponseResponseFut {
        fn transform(result: Result<(String,), fidl::Error>) -> Result<(String), fidl::Error> {
            result.map(|_value| _value.0)
        }
        let send_result = self.client.call_send_raw_query(&mut (), 0x447e655905ccfbf4);
        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)),
        })
    }
    fn r#with_request_no_response(&self, mut arg: &str) -> Result<(), fidl::Error> {
        self.client.send(&mut (arg), 0x7cb47b2f9e76d17d)
    }
    type WithRequestEmptyResponseResponseFut = fidl::client::QueryResponseFut<()>;
    fn r#with_request_empty_response(
        &self,
        mut arg: &str,
    ) -> Self::WithRequestEmptyResponseResponseFut {
        fn transform(result: Result<(), fidl::Error>) -> Result<(), fidl::Error> {
            result.map(|_value| ())
        }
        let send_result = self.client.call_send_raw_query(&mut (arg), 0x65eb512ff0e1c07e);
        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 WithRequestWithResponseResponseFut = fidl::client::QueryResponseFut<(String)>;
    fn r#with_request_with_response(
        &self,
        mut arg: &str,
    ) -> Self::WithRequestWithResponseResponseFut {
        fn transform(result: Result<(String,), fidl::Error>) -> Result<(String), fidl::Error> {
            result.map(|_value| _value.0)
        }
        let send_result = self.client.call_send_raw_query(&mut (arg), 0x1d323510d4447cf1);
        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 OnEmptyResponseResponseFut = fidl::client::QueryResponseFut<()>;
    type OnWithResponseResponseFut = fidl::client::QueryResponseFut<(String)>;
}

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

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

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

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

    fn poll_next(
        mut self: std::pin::Pin<&mut Self>,
        cx: &mut std::task::Context<'_>,
    ) -> std::task::Poll<Option<Self::Item>> {
        let mut 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),
        };
        let (bytes, _handles) = buf.split_mut();
        let (tx_header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;

        std::task::Poll::Ready(Some(match tx_header.ordinal() {
			0x125c87a592bff029 => {
				let mut out_tuple: () = fidl::encoding::Decodable::new_empty();
				fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/WithAndWithoutRequestResponseOnEmptyResponseEvent");
				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((
					WithAndWithoutRequestResponseEvent::OnEmptyResponse {}
				))
			}
			0x177adc0a3ee346c2 => {
				let mut out_tuple: (String,) = fidl::encoding::Decodable::new_empty();
				fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/WithAndWithoutRequestResponseOnWithResponseEvent");
				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((
					WithAndWithoutRequestResponseEvent::OnWithResponse {ret: out_tuple.0,}
				))
			}
			_ => Err(fidl::Error::UnknownOrdinal {
				ordinal: tx_header.ordinal(),
				service_name: <WithAndWithoutRequestResponseMarker as fidl::endpoints::ServiceMarker>::DEBUG_NAME,
			})
		}))
    }
}

#[derive(Debug)]
pub enum WithAndWithoutRequestResponseEvent {
    OnEmptyResponse {},

    OnWithResponse { ret: String },
}

impl WithAndWithoutRequestResponseEvent {
    #[allow(irrefutable_let_patterns)]
    pub fn into_on_empty_response(self) -> Option<()> {
        if let WithAndWithoutRequestResponseEvent::OnEmptyResponse {} = self {
            Some(())
        } else {
            None
        }
    }

    #[allow(irrefutable_let_patterns)]
    pub fn into_on_with_response(self) -> Option<(String)> {
        if let WithAndWithoutRequestResponseEvent::OnWithResponse { ret } = self {
            Some((ret))
        } else {
            None
        }
    }
}

/// A type which can be used to send responses and events into a borrowed channel.
///
/// Note: this should only be used when the channel must be temporarily
/// borrowed. For a typical sending of events, use the send_ methods
/// on the ControlHandle types, which can be acquired through a
/// RequestStream or Responder type.
#[deprecated(note = "Use WithAndWithoutRequestResponseRequestStream / Responder instead")]
pub struct WithAndWithoutRequestResponseServerSender<'a> {
    // Some protocols don't define events which would render this channel unused.
    #[allow(dead_code)]
    channel: &'a fidl::Channel,
}

#[allow(deprecated)]
impl<'a> WithAndWithoutRequestResponseServerSender<'a> {
    pub fn new(channel: &'a fidl::Channel) -> Self {
        Self { channel }
    }
    pub fn send_no_request_empty_response_response(
        &self,
        txid: fidl::client::Txid,
    ) -> Result<(), fidl::Error> {
        fidl::encoding::with_tls_encode_buf(|bytes_, handles_| {
            WithAndWithoutRequestResponseEncoder::encode_no_request_empty_response_response(
                bytes_,
                handles_,
                txid.as_raw_id(),
            )?;
            self.channel
                .write_etc(&*bytes_, &mut *handles_)
                .map_err(fidl::Error::ServerResponseWrite)?;
            Ok(())
        })
    }
    pub fn send_no_request_with_response_response(
        &self,
        txid: fidl::client::Txid,
        mut ret: &str,
    ) -> Result<(), fidl::Error> {
        fidl::encoding::with_tls_encode_buf(|bytes_, handles_| {
            WithAndWithoutRequestResponseEncoder::encode_no_request_with_response_response(
                bytes_,
                handles_,
                txid.as_raw_id(),
                ret,
            )?;
            self.channel
                .write_etc(&*bytes_, &mut *handles_)
                .map_err(fidl::Error::ServerResponseWrite)?;
            Ok(())
        })
    }
    pub fn send_with_request_empty_response_response(
        &self,
        txid: fidl::client::Txid,
    ) -> Result<(), fidl::Error> {
        fidl::encoding::with_tls_encode_buf(|bytes_, handles_| {
            WithAndWithoutRequestResponseEncoder::encode_with_request_empty_response_response(
                bytes_,
                handles_,
                txid.as_raw_id(),
            )?;
            self.channel
                .write_etc(&*bytes_, &mut *handles_)
                .map_err(fidl::Error::ServerResponseWrite)?;
            Ok(())
        })
    }
    pub fn send_with_request_with_response_response(
        &self,
        txid: fidl::client::Txid,
        mut ret: &str,
    ) -> Result<(), fidl::Error> {
        fidl::encoding::with_tls_encode_buf(|bytes_, handles_| {
            WithAndWithoutRequestResponseEncoder::encode_with_request_with_response_response(
                bytes_,
                handles_,
                txid.as_raw_id(),
                ret,
            )?;
            self.channel
                .write_etc(&*bytes_, &mut *handles_)
                .map_err(fidl::Error::ServerResponseWrite)?;
            Ok(())
        })
    }
    pub fn send_on_empty_response(&self) -> Result<(), fidl::Error> {
        fidl::encoding::with_tls_encode_buf(|bytes_, handles_| {
            WithAndWithoutRequestResponseEncoder::encode_on_empty_response_response(
                bytes_, handles_,
            )?;
            self.channel
                .write_etc(&*bytes_, &mut *handles_)
                .map_err(fidl::Error::ServerResponseWrite)?;
            Ok(())
        })
    }
    pub fn send_on_with_response(&self, mut ret: &str) -> Result<(), fidl::Error> {
        fidl::encoding::with_tls_encode_buf(|bytes_, handles_| {
            WithAndWithoutRequestResponseEncoder::encode_on_with_response_response(
                bytes_, handles_, ret,
            )?;
            self.channel
                .write_etc(&*bytes_, &mut *handles_)
                .map_err(fidl::Error::ServerResponseWrite)?;
            Ok(())
        })
    }
}

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

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

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

impl fidl::endpoints::RequestStream for WithAndWithoutRequestResponseRequestStream {
    type Service = WithAndWithoutRequestResponseMarker;

    /// Consume a channel to make a WithAndWithoutRequestResponseRequestStream
    fn from_channel(channel: fidl::AsyncChannel) -> Self {
        Self { inner: std::sync::Arc::new(fidl::ServeInner::new(channel)), is_terminated: false }
    }

    /// ControlHandle for the remote connection
    type ControlHandle = WithAndWithoutRequestResponseControlHandle;

    /// ControlHandle for the remote connection
    fn control_handle(&self) -> Self::ControlHandle {
        WithAndWithoutRequestResponseControlHandle { 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 WithAndWithoutRequestResponseRequestStream {
    type Item = Result<WithAndWithoutRequestResponseRequest, 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 WithAndWithoutRequestResponseRequestStream 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() {
				0x6ad894147d0c6ba4 => {
					let mut req: () = fidl::encoding::Decodable::new_empty();
					fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/WithAndWithoutRequestResponseNoRequestNoResponseRequest");
					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 = WithAndWithoutRequestResponseControlHandle {
						inner: this.inner.clone(),
					};

					Ok(WithAndWithoutRequestResponseRequest::NoRequestNoResponse {control_handle,})
				}
				0x4068f26bf6d868ae => {
					let mut req: () = fidl::encoding::Decodable::new_empty();
					fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/WithAndWithoutRequestResponseNoRequestEmptyResponseRequest");
					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 = WithAndWithoutRequestResponseControlHandle {
						inner: this.inner.clone(),
					};

					Ok(WithAndWithoutRequestResponseRequest::NoRequestEmptyResponse {responder:WithAndWithoutRequestResponseNoRequestEmptyResponseResponder {
								control_handle: std::mem::ManuallyDrop::new(control_handle),
								tx_id: header.tx_id(),
								ordinal: header.ordinal(),
							},})
				}
				0x447e655905ccfbf4 => {
					let mut req: () = fidl::encoding::Decodable::new_empty();
					fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/WithAndWithoutRequestResponseNoRequestWithResponseRequest");
					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 = WithAndWithoutRequestResponseControlHandle {
						inner: this.inner.clone(),
					};

					Ok(WithAndWithoutRequestResponseRequest::NoRequestWithResponse {responder:WithAndWithoutRequestResponseNoRequestWithResponseResponder {
								control_handle: std::mem::ManuallyDrop::new(control_handle),
								tx_id: header.tx_id(),
								ordinal: header.ordinal(),
							},})
				}
				0x7cb47b2f9e76d17d => {
					let mut req: (String,) = fidl::encoding::Decodable::new_empty();
					fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/WithAndWithoutRequestResponseWithRequestNoResponseRequest");
					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 = WithAndWithoutRequestResponseControlHandle {
						inner: this.inner.clone(),
					};

					Ok(WithAndWithoutRequestResponseRequest::WithRequestNoResponse {arg: req.0,control_handle,})
				}
				0x65eb512ff0e1c07e => {
					let mut req: (String,) = fidl::encoding::Decodable::new_empty();
					fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/WithAndWithoutRequestResponseWithRequestEmptyResponseRequest");
					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 = WithAndWithoutRequestResponseControlHandle {
						inner: this.inner.clone(),
					};

					Ok(WithAndWithoutRequestResponseRequest::WithRequestEmptyResponse {arg: req.0,responder:WithAndWithoutRequestResponseWithRequestEmptyResponseResponder {
								control_handle: std::mem::ManuallyDrop::new(control_handle),
								tx_id: header.tx_id(),
								ordinal: header.ordinal(),
							},})
				}
				0x1d323510d4447cf1 => {
					let mut req: (String,) = fidl::encoding::Decodable::new_empty();
					fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/WithAndWithoutRequestResponseWithRequestWithResponseRequest");
					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 = WithAndWithoutRequestResponseControlHandle {
						inner: this.inner.clone(),
					};

					Ok(WithAndWithoutRequestResponseRequest::WithRequestWithResponse {arg: req.0,responder:WithAndWithoutRequestResponseWithRequestWithResponseResponder {
								control_handle: std::mem::ManuallyDrop::new(control_handle),
								tx_id: header.tx_id(),
								ordinal: header.ordinal(),
							},})
				}
				_ => Err(fidl::Error::UnknownOrdinal {
					ordinal: header.ordinal(),
					service_name: <WithAndWithoutRequestResponseMarker as fidl::endpoints::ServiceMarker>::DEBUG_NAME,
				}),
			}))
        })
    }
}

/// Represents a single request.
/// RequestMessages should only be used for manual deserialization when higher level
/// structs such as RequestStream cannot be used. One usually would only encounter
/// such scenarios when working with legacy FIDL code (prior to FIDL generated client/server bindings).
#[derive(Debug)]
#[deprecated(note = "Use WithAndWithoutRequestResponseRequest instead")]
pub enum WithAndWithoutRequestResponseRequestMessage {
    NoRequestNoResponse {},
    NoRequestEmptyResponse { tx_id: fidl::client::Txid },
    NoRequestWithResponse { tx_id: fidl::client::Txid },
    WithRequestNoResponse { arg: String },
    WithRequestEmptyResponse { arg: String, tx_id: fidl::client::Txid },
    WithRequestWithResponse { arg: String, tx_id: fidl::client::Txid },
}

#[allow(deprecated)]
impl WithAndWithoutRequestResponseRequestMessage {
    pub fn decode(
        bytes: &[u8],
        _handles: &mut [fidl::HandleInfo],
    ) -> Result<WithAndWithoutRequestResponseRequestMessage, fidl::Error> {
        let (header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;

        match header.ordinal() {
			0x6ad894147d0c6ba4 => {
				let mut out_tuple: () = fidl::encoding::Decodable::new_empty();
				fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/WithAndWithoutRequestResponseNoRequestNoResponseRequest");
				fidl::trace_blob!("fidl:blob", "decode", bytes);
				fidl::encoding::Decoder::decode_into(&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(WithAndWithoutRequestResponseRequestMessage::NoRequestNoResponse {})
			}
			0x4068f26bf6d868ae => {
				let mut out_tuple: () = fidl::encoding::Decodable::new_empty();
				fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/WithAndWithoutRequestResponseNoRequestEmptyResponseRequest");
				fidl::trace_blob!("fidl:blob", "decode", bytes);
				fidl::encoding::Decoder::decode_into(&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(WithAndWithoutRequestResponseRequestMessage::NoRequestEmptyResponse {tx_id: header.tx_id().into(),})
			}
			0x447e655905ccfbf4 => {
				let mut out_tuple: () = fidl::encoding::Decodable::new_empty();
				fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/WithAndWithoutRequestResponseNoRequestWithResponseRequest");
				fidl::trace_blob!("fidl:blob", "decode", bytes);
				fidl::encoding::Decoder::decode_into(&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(WithAndWithoutRequestResponseRequestMessage::NoRequestWithResponse {tx_id: header.tx_id().into(),})
			}
			0x7cb47b2f9e76d17d => {
				let mut out_tuple: (String,) = fidl::encoding::Decodable::new_empty();
				fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/WithAndWithoutRequestResponseWithRequestNoResponseRequest");
				fidl::trace_blob!("fidl:blob", "decode", bytes);
				fidl::encoding::Decoder::decode_into(&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(WithAndWithoutRequestResponseRequestMessage::WithRequestNoResponse {arg: out_tuple.0,})
			}
			0x65eb512ff0e1c07e => {
				let mut out_tuple: (String,) = fidl::encoding::Decodable::new_empty();
				fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/WithAndWithoutRequestResponseWithRequestEmptyResponseRequest");
				fidl::trace_blob!("fidl:blob", "decode", bytes);
				fidl::encoding::Decoder::decode_into(&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(WithAndWithoutRequestResponseRequestMessage::WithRequestEmptyResponse {arg: out_tuple.0,tx_id: header.tx_id().into(),})
			}
			0x1d323510d4447cf1 => {
				let mut out_tuple: (String,) = fidl::encoding::Decodable::new_empty();
				fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/WithAndWithoutRequestResponseWithRequestWithResponseRequest");
				fidl::trace_blob!("fidl:blob", "decode", bytes);
				fidl::encoding::Decoder::decode_into(&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(WithAndWithoutRequestResponseRequestMessage::WithRequestWithResponse {arg: out_tuple.0,tx_id: header.tx_id().into(),})
			}
			_ => Err(fidl::Error::UnknownOrdinal {
				ordinal: header.ordinal(),
				service_name: <WithAndWithoutRequestResponseMarker as fidl::endpoints::ServiceMarker>::DEBUG_NAME,
			}),
		}
    }
}
#[derive(Debug)]
pub enum WithAndWithoutRequestResponseRequest {
    NoRequestNoResponse {
        control_handle: WithAndWithoutRequestResponseControlHandle,
    },
    NoRequestEmptyResponse {
        responder: WithAndWithoutRequestResponseNoRequestEmptyResponseResponder,
    },
    NoRequestWithResponse {
        responder: WithAndWithoutRequestResponseNoRequestWithResponseResponder,
    },
    WithRequestNoResponse {
        arg: String,
        control_handle: WithAndWithoutRequestResponseControlHandle,
    },
    WithRequestEmptyResponse {
        arg: String,
        responder: WithAndWithoutRequestResponseWithRequestEmptyResponseResponder,
    },
    WithRequestWithResponse {
        arg: String,
        responder: WithAndWithoutRequestResponseWithRequestWithResponseResponder,
    },
}

impl WithAndWithoutRequestResponseRequest {
    #[allow(irrefutable_let_patterns)]
    pub fn into_no_request_no_response(
        self,
    ) -> Option<(WithAndWithoutRequestResponseControlHandle)> {
        if let WithAndWithoutRequestResponseRequest::NoRequestNoResponse { control_handle } = self {
            Some((control_handle))
        } else {
            None
        }
    }

    #[allow(irrefutable_let_patterns)]
    pub fn into_no_request_empty_response(
        self,
    ) -> Option<(WithAndWithoutRequestResponseNoRequestEmptyResponseResponder)> {
        if let WithAndWithoutRequestResponseRequest::NoRequestEmptyResponse { responder } = self {
            Some((responder))
        } else {
            None
        }
    }

    #[allow(irrefutable_let_patterns)]
    pub fn into_no_request_with_response(
        self,
    ) -> Option<(WithAndWithoutRequestResponseNoRequestWithResponseResponder)> {
        if let WithAndWithoutRequestResponseRequest::NoRequestWithResponse { responder } = self {
            Some((responder))
        } else {
            None
        }
    }

    #[allow(irrefutable_let_patterns)]
    pub fn into_with_request_no_response(
        self,
    ) -> Option<(String, WithAndWithoutRequestResponseControlHandle)> {
        if let WithAndWithoutRequestResponseRequest::WithRequestNoResponse { arg, control_handle } =
            self
        {
            Some((arg, control_handle))
        } else {
            None
        }
    }

    #[allow(irrefutable_let_patterns)]
    pub fn into_with_request_empty_response(
        self,
    ) -> Option<(String, WithAndWithoutRequestResponseWithRequestEmptyResponseResponder)> {
        if let WithAndWithoutRequestResponseRequest::WithRequestEmptyResponse { arg, responder } =
            self
        {
            Some((arg, responder))
        } else {
            None
        }
    }

    #[allow(irrefutable_let_patterns)]
    pub fn into_with_request_with_response(
        self,
    ) -> Option<(String, WithAndWithoutRequestResponseWithRequestWithResponseResponder)> {
        if let WithAndWithoutRequestResponseRequest::WithRequestWithResponse { arg, responder } =
            self
        {
            Some((arg, responder))
        } else {
            None
        }
    }

    /// Name of the method defined in FIDL
    pub fn method_name(&self) -> &'static str {
        match *self {
            WithAndWithoutRequestResponseRequest::NoRequestNoResponse { .. } => {
                "no_request_no_response"
            }
            WithAndWithoutRequestResponseRequest::NoRequestEmptyResponse { .. } => {
                "no_request_empty_response"
            }
            WithAndWithoutRequestResponseRequest::NoRequestWithResponse { .. } => {
                "no_request_with_response"
            }
            WithAndWithoutRequestResponseRequest::WithRequestNoResponse { .. } => {
                "with_request_no_response"
            }
            WithAndWithoutRequestResponseRequest::WithRequestEmptyResponse { .. } => {
                "with_request_empty_response"
            }
            WithAndWithoutRequestResponseRequest::WithRequestWithResponse { .. } => {
                "with_request_with_response"
            }
        }
    }
}

pub struct WithAndWithoutRequestResponseEncoder;

impl WithAndWithoutRequestResponseEncoder {
    pub fn encode_no_request_no_response_request<'a>(
        out_bytes: &'a mut Vec<u8>,
        out_handles: &'a mut Vec<fidl::HandleDisposition<'static>>,
    ) -> Result<(), fidl::Error> {
        let header = fidl::encoding::TransactionHeader::new(0, 0x6ad894147d0c6ba4);
        let mut body = ();
        let mut msg = fidl::encoding::TransactionMessage { header, body: &mut body };
        fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/WithAndWithoutRequestResponseNoRequestNoResponseRequest");
        fidl::encoding::Encoder::encode(out_bytes, out_handles, &mut msg)?;
        fidl::trace_blob!("fidl:blob", "encode", out_bytes.as_slice());
        fidl::duration_end!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => out_bytes.len() as u32, "handle_count" => out_handles.len() as u32);
        Ok(())
    }
    pub fn encode_no_request_empty_response_request<'a>(
        out_bytes: &'a mut Vec<u8>,
        out_handles: &'a mut Vec<fidl::HandleDisposition<'static>>,
        tx_id: u32,
    ) -> Result<(), fidl::Error> {
        let header = fidl::encoding::TransactionHeader::new(tx_id, 0x4068f26bf6d868ae);
        let mut body = ();
        let mut msg = fidl::encoding::TransactionMessage { header, body: &mut body };
        fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/WithAndWithoutRequestResponseNoRequestEmptyResponseRequest");
        fidl::encoding::Encoder::encode(out_bytes, out_handles, &mut msg)?;
        fidl::trace_blob!("fidl:blob", "encode", out_bytes.as_slice());
        fidl::duration_end!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => out_bytes.len() as u32, "handle_count" => out_handles.len() as u32);
        Ok(())
    }
    pub fn encode_no_request_empty_response_response<'a>(
        out_bytes: &'a mut Vec<u8>,
        out_handles: &'a mut Vec<fidl::HandleDisposition<'static>>,
        tx_id: u32,
    ) -> Result<(), fidl::Error> {
        let header = fidl::encoding::TransactionHeader::new(tx_id, 0x4068f26bf6d868ae);
        let mut body = ();
        let mut msg = fidl::encoding::TransactionMessage { header, body: &mut body };

        fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/WithAndWithoutRequestResponseNoRequestEmptyResponseResponse");
        fidl::encoding::Encoder::encode(out_bytes, out_handles, &mut msg)?;
        fidl::trace_blob!("fidl:blob", "encode", out_bytes.as_slice());
        fidl::duration_end!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => out_bytes.len() as u32, "handle_count" => out_handles.len() as u32);

        Ok(())
    }
    pub fn encode_no_request_with_response_request<'a>(
        out_bytes: &'a mut Vec<u8>,
        out_handles: &'a mut Vec<fidl::HandleDisposition<'static>>,
        tx_id: u32,
    ) -> Result<(), fidl::Error> {
        let header = fidl::encoding::TransactionHeader::new(tx_id, 0x447e655905ccfbf4);
        let mut body = ();
        let mut msg = fidl::encoding::TransactionMessage { header, body: &mut body };
        fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/WithAndWithoutRequestResponseNoRequestWithResponseRequest");
        fidl::encoding::Encoder::encode(out_bytes, out_handles, &mut msg)?;
        fidl::trace_blob!("fidl:blob", "encode", out_bytes.as_slice());
        fidl::duration_end!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => out_bytes.len() as u32, "handle_count" => out_handles.len() as u32);
        Ok(())
    }
    pub fn encode_no_request_with_response_response<'a>(
        out_bytes: &'a mut Vec<u8>,
        out_handles: &'a mut Vec<fidl::HandleDisposition<'static>>,
        tx_id: u32,
        mut in_ret: &str,
    ) -> Result<(), fidl::Error> {
        let header = fidl::encoding::TransactionHeader::new(tx_id, 0x447e655905ccfbf4);
        let mut body = (in_ret,);
        let mut msg = fidl::encoding::TransactionMessage { header, body: &mut body };

        fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/WithAndWithoutRequestResponseNoRequestWithResponseResponse");
        fidl::encoding::Encoder::encode(out_bytes, out_handles, &mut msg)?;
        fidl::trace_blob!("fidl:blob", "encode", out_bytes.as_slice());
        fidl::duration_end!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => out_bytes.len() as u32, "handle_count" => out_handles.len() as u32);

        Ok(())
    }
    pub fn encode_with_request_no_response_request<'a>(
        out_bytes: &'a mut Vec<u8>,
        out_handles: &'a mut Vec<fidl::HandleDisposition<'static>>,
        mut in_arg: &str,
    ) -> Result<(), fidl::Error> {
        let header = fidl::encoding::TransactionHeader::new(0, 0x7cb47b2f9e76d17d);
        let mut body = (in_arg,);
        let mut msg = fidl::encoding::TransactionMessage { header, body: &mut body };
        fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/WithAndWithoutRequestResponseWithRequestNoResponseRequest");
        fidl::encoding::Encoder::encode(out_bytes, out_handles, &mut msg)?;
        fidl::trace_blob!("fidl:blob", "encode", out_bytes.as_slice());
        fidl::duration_end!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => out_bytes.len() as u32, "handle_count" => out_handles.len() as u32);
        Ok(())
    }
    pub fn encode_with_request_empty_response_request<'a>(
        out_bytes: &'a mut Vec<u8>,
        out_handles: &'a mut Vec<fidl::HandleDisposition<'static>>,
        tx_id: u32,
        mut in_arg: &str,
    ) -> Result<(), fidl::Error> {
        let header = fidl::encoding::TransactionHeader::new(tx_id, 0x65eb512ff0e1c07e);
        let mut body = (in_arg,);
        let mut msg = fidl::encoding::TransactionMessage { header, body: &mut body };
        fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/WithAndWithoutRequestResponseWithRequestEmptyResponseRequest");
        fidl::encoding::Encoder::encode(out_bytes, out_handles, &mut msg)?;
        fidl::trace_blob!("fidl:blob", "encode", out_bytes.as_slice());
        fidl::duration_end!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => out_bytes.len() as u32, "handle_count" => out_handles.len() as u32);
        Ok(())
    }
    pub fn encode_with_request_empty_response_response<'a>(
        out_bytes: &'a mut Vec<u8>,
        out_handles: &'a mut Vec<fidl::HandleDisposition<'static>>,
        tx_id: u32,
    ) -> Result<(), fidl::Error> {
        let header = fidl::encoding::TransactionHeader::new(tx_id, 0x65eb512ff0e1c07e);
        let mut body = ();
        let mut msg = fidl::encoding::TransactionMessage { header, body: &mut body };

        fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/WithAndWithoutRequestResponseWithRequestEmptyResponseResponse");
        fidl::encoding::Encoder::encode(out_bytes, out_handles, &mut msg)?;
        fidl::trace_blob!("fidl:blob", "encode", out_bytes.as_slice());
        fidl::duration_end!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => out_bytes.len() as u32, "handle_count" => out_handles.len() as u32);

        Ok(())
    }
    pub fn encode_with_request_with_response_request<'a>(
        out_bytes: &'a mut Vec<u8>,
        out_handles: &'a mut Vec<fidl::HandleDisposition<'static>>,
        tx_id: u32,
        mut in_arg: &str,
    ) -> Result<(), fidl::Error> {
        let header = fidl::encoding::TransactionHeader::new(tx_id, 0x1d323510d4447cf1);
        let mut body = (in_arg,);
        let mut msg = fidl::encoding::TransactionMessage { header, body: &mut body };
        fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/WithAndWithoutRequestResponseWithRequestWithResponseRequest");
        fidl::encoding::Encoder::encode(out_bytes, out_handles, &mut msg)?;
        fidl::trace_blob!("fidl:blob", "encode", out_bytes.as_slice());
        fidl::duration_end!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => out_bytes.len() as u32, "handle_count" => out_handles.len() as u32);
        Ok(())
    }
    pub fn encode_with_request_with_response_response<'a>(
        out_bytes: &'a mut Vec<u8>,
        out_handles: &'a mut Vec<fidl::HandleDisposition<'static>>,
        tx_id: u32,
        mut in_ret: &str,
    ) -> Result<(), fidl::Error> {
        let header = fidl::encoding::TransactionHeader::new(tx_id, 0x1d323510d4447cf1);
        let mut body = (in_ret,);
        let mut msg = fidl::encoding::TransactionMessage { header, body: &mut body };

        fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/WithAndWithoutRequestResponseWithRequestWithResponseResponse");
        fidl::encoding::Encoder::encode(out_bytes, out_handles, &mut msg)?;
        fidl::trace_blob!("fidl:blob", "encode", out_bytes.as_slice());
        fidl::duration_end!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => out_bytes.len() as u32, "handle_count" => out_handles.len() as u32);

        Ok(())
    }
    pub fn encode_on_empty_response_response<'a>(
        out_bytes: &'a mut Vec<u8>,
        out_handles: &'a mut Vec<fidl::HandleDisposition<'static>>,
    ) -> Result<(), fidl::Error> {
        let header = fidl::encoding::TransactionHeader::new(0, 0x125c87a592bff029);
        let mut body = ();
        let mut msg = fidl::encoding::TransactionMessage { header, body: &mut body };

        fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/WithAndWithoutRequestResponseOnEmptyResponseResponse");
        fidl::encoding::Encoder::encode(out_bytes, out_handles, &mut msg)?;
        fidl::trace_blob!("fidl:blob", "encode", out_bytes.as_slice());
        fidl::duration_end!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => out_bytes.len() as u32, "handle_count" => out_handles.len() as u32);

        Ok(())
    }
    pub fn encode_on_with_response_response<'a>(
        out_bytes: &'a mut Vec<u8>,
        out_handles: &'a mut Vec<fidl::HandleDisposition<'static>>,
        mut in_ret: &str,
    ) -> Result<(), fidl::Error> {
        let header = fidl::encoding::TransactionHeader::new(0, 0x177adc0a3ee346c2);
        let mut body = (in_ret,);
        let mut msg = fidl::encoding::TransactionMessage { header, body: &mut body };

        fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/WithAndWithoutRequestResponseOnWithResponseResponse");
        fidl::encoding::Encoder::encode(out_bytes, out_handles, &mut msg)?;
        fidl::trace_blob!("fidl:blob", "encode", out_bytes.as_slice());
        fidl::duration_end!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => out_bytes.len() as u32, "handle_count" => out_handles.len() as u32);

        Ok(())
    }
}

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

impl WithAndWithoutRequestResponseControlHandle {
    /// Set the server to shutdown. The underlying channel is only closed the
    /// next time the stream is polled.
    pub fn shutdown(&self) {
        self.inner.shutdown()
    }

    pub fn shutdown_with_epitaph(&self, status: zx_status::Status) {
        self.inner.shutdown_with_epitaph(status)
    }
    pub fn send_on_empty_response(&self) -> Result<(), fidl::Error> {
        let mut response = ();

        let mut msg = fidl::encoding::TransactionMessage {
            header: fidl::encoding::TransactionHeader::new(0, 0x125c87a592bff029),
            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_with_response(&self, mut ret: &str) -> Result<(), fidl::Error> {
        let mut response = (ret);

        let mut msg = fidl::encoding::TransactionMessage {
            header: fidl::encoding::TransactionHeader::new(0, 0x177adc0a3ee346c2),
            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 WithAndWithoutRequestResponseNoRequestEmptyResponseResponder {
    control_handle: std::mem::ManuallyDrop<WithAndWithoutRequestResponseControlHandle>,
    tx_id: u32,
    ordinal: u64,
}

/// Set the the channel to be shutdown (see [`WithAndWithoutRequestResponseControlHandle::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 WithAndWithoutRequestResponseNoRequestEmptyResponseResponder {
    fn drop(&mut self) {
        self.control_handle.shutdown();
        // Safety: drops once, never accessed again
        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
    }
}

impl WithAndWithoutRequestResponseNoRequestEmptyResponseResponder {
    pub fn control_handle(&self) -> &WithAndWithoutRequestResponseControlHandle {
        &self.control_handle
    }

    /// Drop the Responder without setting the channel to shutdown.
    ///
    /// This method shouldn't normally be used-- instead, send a response
    /// to prevent the channel from shutting down.
    pub 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);
    }

    /// Sends a response to the FIDL transaction.
    ///
    /// Sets the channel to shutdown if an error occurs.
    pub fn send(self) -> Result<(), fidl::Error> {
        let r = self.send_raw();
        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) -> Result<(), fidl::Error> {
        let r = self.send_raw();
        self.drop_without_shutdown();
        r
    }

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

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

        fidl::encoding::with_tls_encode_buf(|bytes, handles| {
            fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/WithAndWithoutRequestResponseNoRequestEmptyResponseResponse");
            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 WithAndWithoutRequestResponseNoRequestWithResponseResponder {
    control_handle: std::mem::ManuallyDrop<WithAndWithoutRequestResponseControlHandle>,
    tx_id: u32,
    ordinal: u64,
}

/// Set the the channel to be shutdown (see [`WithAndWithoutRequestResponseControlHandle::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 WithAndWithoutRequestResponseNoRequestWithResponseResponder {
    fn drop(&mut self) {
        self.control_handle.shutdown();
        // Safety: drops once, never accessed again
        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
    }
}

impl WithAndWithoutRequestResponseNoRequestWithResponseResponder {
    pub fn control_handle(&self) -> &WithAndWithoutRequestResponseControlHandle {
        &self.control_handle
    }

    /// Drop the Responder without setting the channel to shutdown.
    ///
    /// This method shouldn't normally be used-- instead, send a response
    /// to prevent the channel from shutting down.
    pub 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);
    }

    /// Sends a response to the FIDL transaction.
    ///
    /// Sets the channel to shutdown if an error occurs.
    pub fn send(self, mut ret: &str) -> Result<(), fidl::Error> {
        let r = self.send_raw(ret);
        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 ret: &str) -> Result<(), fidl::Error> {
        let r = self.send_raw(ret);
        self.drop_without_shutdown();
        r
    }

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

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

        fidl::encoding::with_tls_encode_buf(|bytes, handles| {
            fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/WithAndWithoutRequestResponseNoRequestWithResponseResponse");
            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 WithAndWithoutRequestResponseWithRequestEmptyResponseResponder {
    control_handle: std::mem::ManuallyDrop<WithAndWithoutRequestResponseControlHandle>,
    tx_id: u32,
    ordinal: u64,
}

/// Set the the channel to be shutdown (see [`WithAndWithoutRequestResponseControlHandle::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 WithAndWithoutRequestResponseWithRequestEmptyResponseResponder {
    fn drop(&mut self) {
        self.control_handle.shutdown();
        // Safety: drops once, never accessed again
        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
    }
}

impl WithAndWithoutRequestResponseWithRequestEmptyResponseResponder {
    pub fn control_handle(&self) -> &WithAndWithoutRequestResponseControlHandle {
        &self.control_handle
    }

    /// Drop the Responder without setting the channel to shutdown.
    ///
    /// This method shouldn't normally be used-- instead, send a response
    /// to prevent the channel from shutting down.
    pub 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);
    }

    /// Sends a response to the FIDL transaction.
    ///
    /// Sets the channel to shutdown if an error occurs.
    pub fn send(self) -> Result<(), fidl::Error> {
        let r = self.send_raw();
        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) -> Result<(), fidl::Error> {
        let r = self.send_raw();
        self.drop_without_shutdown();
        r
    }

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

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

        fidl::encoding::with_tls_encode_buf(|bytes, handles| {
            fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/WithAndWithoutRequestResponseWithRequestEmptyResponseResponse");
            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 WithAndWithoutRequestResponseWithRequestWithResponseResponder {
    control_handle: std::mem::ManuallyDrop<WithAndWithoutRequestResponseControlHandle>,
    tx_id: u32,
    ordinal: u64,
}

/// Set the the channel to be shutdown (see [`WithAndWithoutRequestResponseControlHandle::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 WithAndWithoutRequestResponseWithRequestWithResponseResponder {
    fn drop(&mut self) {
        self.control_handle.shutdown();
        // Safety: drops once, never accessed again
        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
    }
}

impl WithAndWithoutRequestResponseWithRequestWithResponseResponder {
    pub fn control_handle(&self) -> &WithAndWithoutRequestResponseControlHandle {
        &self.control_handle
    }

    /// Drop the Responder without setting the channel to shutdown.
    ///
    /// This method shouldn't normally be used-- instead, send a response
    /// to prevent the channel from shutting down.
    pub 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);
    }

    /// Sends a response to the FIDL transaction.
    ///
    /// Sets the channel to shutdown if an error occurs.
    pub fn send(self, mut ret: &str) -> Result<(), fidl::Error> {
        let r = self.send_raw(ret);
        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 ret: &str) -> Result<(), fidl::Error> {
        let r = self.send_raw(ret);
        self.drop_without_shutdown();
        r
    }

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

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

        fidl::encoding::with_tls_encode_buf(|bytes, handles| {
            fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/WithAndWithoutRequestResponseWithRequestWithResponseResponse");
            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(())
        })
    }
}

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

impl fidl::endpoints::ServiceMarker for WithErrorSyntaxMarker {
    type Proxy = WithErrorSyntaxProxy;
    type RequestStream = WithErrorSyntaxRequestStream;
    const DEBUG_NAME: &'static str = "(anonymous) WithErrorSyntax";
}

pub trait WithErrorSyntaxProxyInterface: Send + Sync {
    type ResponseAsStructResponseFut: std::future::Future<Output = Result<(WithErrorSyntaxResponseAsStructResult), fidl::Error>>
        + Send;
    fn r#response_as_struct(&self) -> Self::ResponseAsStructResponseFut;
    type ErrorAsPrimitiveResponseFut: std::future::Future<Output = Result<(WithErrorSyntaxErrorAsPrimitiveResult), fidl::Error>>
        + Send;
    fn r#error_as_primitive(&self) -> Self::ErrorAsPrimitiveResponseFut;
    type ErrorAsEnumResponseFut: std::future::Future<Output = Result<(WithErrorSyntaxErrorAsEnumResult), fidl::Error>>
        + Send;
    fn r#error_as_enum(&self) -> Self::ErrorAsEnumResponseFut;
}

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

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

    pub fn into_channel(self) -> fidl::Channel {
        self.client.into_channel()
    }
    pub fn r#response_as_struct(
        &mut self,
        ___deadline: zx::Time,
    ) -> Result<(WithErrorSyntaxResponseAsStructResult), fidl::Error> {
        let _value: (WithErrorSyntaxResponseAsStructResultHandleWrapper) =
            self.client.send_query(&mut (), 0x3784d38864674290, ___deadline)?;
        Ok(_value.map(|_value| (_value.0, _value.1, _value.2)))
    }
    pub fn r#error_as_primitive(
        &mut self,
        ___deadline: zx::Time,
    ) -> Result<(WithErrorSyntaxErrorAsPrimitiveResult), fidl::Error> {
        let _value: (WithErrorSyntaxErrorAsPrimitiveResultHandleWrapper) =
            self.client.send_query(&mut (), 0x2f7c390f3cdef4ce, ___deadline)?;
        Ok(_value.map(|_value| ()))
    }
    pub fn r#error_as_enum(
        &mut self,
        ___deadline: zx::Time,
    ) -> Result<(WithErrorSyntaxErrorAsEnumResult), fidl::Error> {
        let _value: (WithErrorSyntaxErrorAsEnumResultHandleWrapper) =
            self.client.send_query(&mut (), 0x8b550d7c29f740c, ___deadline)?;
        Ok(_value.map(|_value| ()))
    }
}

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

impl fidl::endpoints::Proxy for WithErrorSyntaxProxy {
    type Service = WithErrorSyntaxMarker;

    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 WithErrorSyntaxProxy {
    /// Create a new Proxy for WithErrorSyntax
    pub fn new(channel: fidl::AsyncChannel) -> Self {
        let service_name = <WithErrorSyntaxMarker as fidl::endpoints::ServiceMarker>::DEBUG_NAME;
        Self { client: fidl::client::Client::new(channel, service_name) }
    }

    /// Get a Stream of events from the remote end of the WithErrorSyntax protocol
    ///
    /// # Panics
    ///
    /// Panics if the event stream was already taken.
    pub fn take_event_stream(&self) -> WithErrorSyntaxEventStream {
        WithErrorSyntaxEventStream { event_receiver: self.client.take_event_receiver() }
    }
    pub fn r#response_as_struct(
        &self,
    ) -> fidl::client::QueryResponseFut<(WithErrorSyntaxResponseAsStructResult)> {
        WithErrorSyntaxProxyInterface::r#response_as_struct(self)
    }
    pub fn r#error_as_primitive(
        &self,
    ) -> fidl::client::QueryResponseFut<(WithErrorSyntaxErrorAsPrimitiveResult)> {
        WithErrorSyntaxProxyInterface::r#error_as_primitive(self)
    }
    pub fn r#error_as_enum(
        &self,
    ) -> fidl::client::QueryResponseFut<(WithErrorSyntaxErrorAsEnumResult)> {
        WithErrorSyntaxProxyInterface::r#error_as_enum(self)
    }
}

impl WithErrorSyntaxProxyInterface for WithErrorSyntaxProxy {
    type ResponseAsStructResponseFut =
        fidl::client::QueryResponseFut<(WithErrorSyntaxResponseAsStructResult)>;
    fn r#response_as_struct(&self) -> Self::ResponseAsStructResponseFut {
        fn transform(
            result: Result<(WithErrorSyntaxResponseAsStructResultHandleWrapper), fidl::Error>,
        ) -> Result<(WithErrorSyntaxResponseAsStructResult), fidl::Error> {
            result.map(|_value| _value.map(|_value| (_value.0, _value.1, _value.2)))
        }
        let send_result = self.client.call_send_raw_query(&mut (), 0x3784d38864674290);
        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 ErrorAsPrimitiveResponseFut =
        fidl::client::QueryResponseFut<(WithErrorSyntaxErrorAsPrimitiveResult)>;
    fn r#error_as_primitive(&self) -> Self::ErrorAsPrimitiveResponseFut {
        fn transform(
            result: Result<(WithErrorSyntaxErrorAsPrimitiveResultHandleWrapper), fidl::Error>,
        ) -> Result<(WithErrorSyntaxErrorAsPrimitiveResult), fidl::Error> {
            result.map(|_value| _value.map(|_value| ()))
        }
        let send_result = self.client.call_send_raw_query(&mut (), 0x2f7c390f3cdef4ce);
        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 ErrorAsEnumResponseFut =
        fidl::client::QueryResponseFut<(WithErrorSyntaxErrorAsEnumResult)>;
    fn r#error_as_enum(&self) -> Self::ErrorAsEnumResponseFut {
        fn transform(
            result: Result<(WithErrorSyntaxErrorAsEnumResultHandleWrapper), fidl::Error>,
        ) -> Result<(WithErrorSyntaxErrorAsEnumResult), fidl::Error> {
            result.map(|_value| _value.map(|_value| ()))
        }
        let send_result = self.client.call_send_raw_query(&mut (), 0x8b550d7c29f740c);
        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)),
        })
    }
}

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

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

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

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

    fn poll_next(
        mut self: std::pin::Pin<&mut Self>,
        cx: &mut std::task::Context<'_>,
    ) -> std::task::Poll<Option<Self::Item>> {
        let mut 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),
        };
        let (bytes, _handles) = buf.split_mut();
        let (tx_header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;

        std::task::Poll::Ready(Some(match tx_header.ordinal() {
            _ => Err(fidl::Error::UnknownOrdinal {
                ordinal: tx_header.ordinal(),
                service_name: <WithErrorSyntaxMarker as fidl::endpoints::ServiceMarker>::DEBUG_NAME,
            }),
        }))
    }
}

#[derive(Debug)]
pub enum WithErrorSyntaxEvent {}

impl WithErrorSyntaxEvent {}

/// A type which can be used to send responses and events into a borrowed channel.
///
/// Note: this should only be used when the channel must be temporarily
/// borrowed. For a typical sending of events, use the send_ methods
/// on the ControlHandle types, which can be acquired through a
/// RequestStream or Responder type.
#[deprecated(note = "Use WithErrorSyntaxRequestStream / Responder instead")]
pub struct WithErrorSyntaxServerSender<'a> {
    // Some protocols don't define events which would render this channel unused.
    #[allow(dead_code)]
    channel: &'a fidl::Channel,
}

#[allow(deprecated)]
impl<'a> WithErrorSyntaxServerSender<'a> {
    pub fn new(channel: &'a fidl::Channel) -> Self {
        Self { channel }
    }
    pub fn send_response_as_struct_response(
        &self,
        txid: fidl::client::Txid,
        mut result: &mut WithErrorSyntaxResponseAsStructResult,
    ) -> Result<(), fidl::Error> {
        fidl::encoding::with_tls_encode_buf(|bytes_, handles_| {
            WithErrorSyntaxEncoder::encode_response_as_struct_response(
                bytes_,
                handles_,
                txid.as_raw_id(),
                result,
            )?;
            self.channel
                .write_etc(&*bytes_, &mut *handles_)
                .map_err(fidl::Error::ServerResponseWrite)?;
            Ok(())
        })
    }
    pub fn send_error_as_primitive_response(
        &self,
        txid: fidl::client::Txid,
        mut result: &mut WithErrorSyntaxErrorAsPrimitiveResult,
    ) -> Result<(), fidl::Error> {
        fidl::encoding::with_tls_encode_buf(|bytes_, handles_| {
            WithErrorSyntaxEncoder::encode_error_as_primitive_response(
                bytes_,
                handles_,
                txid.as_raw_id(),
                result,
            )?;
            self.channel
                .write_etc(&*bytes_, &mut *handles_)
                .map_err(fidl::Error::ServerResponseWrite)?;
            Ok(())
        })
    }
    pub fn send_error_as_enum_response(
        &self,
        txid: fidl::client::Txid,
        mut result: &mut WithErrorSyntaxErrorAsEnumResult,
    ) -> Result<(), fidl::Error> {
        fidl::encoding::with_tls_encode_buf(|bytes_, handles_| {
            WithErrorSyntaxEncoder::encode_error_as_enum_response(
                bytes_,
                handles_,
                txid.as_raw_id(),
                result,
            )?;
            self.channel
                .write_etc(&*bytes_, &mut *handles_)
                .map_err(fidl::Error::ServerResponseWrite)?;
            Ok(())
        })
    }
}

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

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

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

impl fidl::endpoints::RequestStream for WithErrorSyntaxRequestStream {
    type Service = WithErrorSyntaxMarker;

    /// Consume a channel to make a WithErrorSyntaxRequestStream
    fn from_channel(channel: fidl::AsyncChannel) -> Self {
        Self { inner: std::sync::Arc::new(fidl::ServeInner::new(channel)), is_terminated: false }
    }

    /// ControlHandle for the remote connection
    type ControlHandle = WithErrorSyntaxControlHandle;

    /// ControlHandle for the remote connection
    fn control_handle(&self) -> Self::ControlHandle {
        WithErrorSyntaxControlHandle { 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 WithErrorSyntaxRequestStream {
    type Item = Result<WithErrorSyntaxRequest, 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 WithErrorSyntaxRequestStream 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() {
                0x3784d38864674290 => {
                    let mut req: () = fidl::encoding::Decodable::new_empty();
                    fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/WithErrorSyntaxResponseAsStructRequest");
                    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 = WithErrorSyntaxControlHandle { inner: this.inner.clone() };

                    Ok(WithErrorSyntaxRequest::ResponseAsStruct {
                        responder: WithErrorSyntaxResponseAsStructResponder {
                            control_handle: std::mem::ManuallyDrop::new(control_handle),
                            tx_id: header.tx_id(),
                            ordinal: header.ordinal(),
                        },
                    })
                }
                0x2f7c390f3cdef4ce => {
                    let mut req: () = fidl::encoding::Decodable::new_empty();
                    fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/WithErrorSyntaxErrorAsPrimitiveRequest");
                    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 = WithErrorSyntaxControlHandle { inner: this.inner.clone() };

                    Ok(WithErrorSyntaxRequest::ErrorAsPrimitive {
                        responder: WithErrorSyntaxErrorAsPrimitiveResponder {
                            control_handle: std::mem::ManuallyDrop::new(control_handle),
                            tx_id: header.tx_id(),
                            ordinal: header.ordinal(),
                        },
                    })
                }
                0x8b550d7c29f740c => {
                    let mut req: () = fidl::encoding::Decodable::new_empty();
                    fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/WithErrorSyntaxErrorAsEnumRequest");
                    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 = WithErrorSyntaxControlHandle { inner: this.inner.clone() };

                    Ok(WithErrorSyntaxRequest::ErrorAsEnum {
                        responder: WithErrorSyntaxErrorAsEnumResponder {
                            control_handle: std::mem::ManuallyDrop::new(control_handle),
                            tx_id: header.tx_id(),
                            ordinal: header.ordinal(),
                        },
                    })
                }
                _ => Err(fidl::Error::UnknownOrdinal {
                    ordinal: header.ordinal(),
                    service_name:
                        <WithErrorSyntaxMarker as fidl::endpoints::ServiceMarker>::DEBUG_NAME,
                }),
            }))
        })
    }
}

/// Represents a single request.
/// RequestMessages should only be used for manual deserialization when higher level
/// structs such as RequestStream cannot be used. One usually would only encounter
/// such scenarios when working with legacy FIDL code (prior to FIDL generated client/server bindings).
#[derive(Debug)]
#[deprecated(note = "Use WithErrorSyntaxRequest instead")]
pub enum WithErrorSyntaxRequestMessage {
    ResponseAsStruct { tx_id: fidl::client::Txid },
    ErrorAsPrimitive { tx_id: fidl::client::Txid },
    ErrorAsEnum { tx_id: fidl::client::Txid },
}

#[allow(deprecated)]
impl WithErrorSyntaxRequestMessage {
    pub fn decode(
        bytes: &[u8],
        _handles: &mut [fidl::HandleInfo],
    ) -> Result<WithErrorSyntaxRequestMessage, fidl::Error> {
        let (header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;

        match header.ordinal() {
            0x3784d38864674290 => {
                let mut out_tuple: () = fidl::encoding::Decodable::new_empty();
                fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/WithErrorSyntaxResponseAsStructRequest");
                fidl::trace_blob!("fidl:blob", "decode", bytes);
                fidl::encoding::Decoder::decode_into(
                    &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(WithErrorSyntaxRequestMessage::ResponseAsStruct { tx_id: header.tx_id().into() })
            }
            0x2f7c390f3cdef4ce => {
                let mut out_tuple: () = fidl::encoding::Decodable::new_empty();
                fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/WithErrorSyntaxErrorAsPrimitiveRequest");
                fidl::trace_blob!("fidl:blob", "decode", bytes);
                fidl::encoding::Decoder::decode_into(
                    &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(WithErrorSyntaxRequestMessage::ErrorAsPrimitive { tx_id: header.tx_id().into() })
            }
            0x8b550d7c29f740c => {
                let mut out_tuple: () = fidl::encoding::Decodable::new_empty();
                fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/WithErrorSyntaxErrorAsEnumRequest");
                fidl::trace_blob!("fidl:blob", "decode", bytes);
                fidl::encoding::Decoder::decode_into(
                    &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(WithErrorSyntaxRequestMessage::ErrorAsEnum { tx_id: header.tx_id().into() })
            }
            _ => Err(fidl::Error::UnknownOrdinal {
                ordinal: header.ordinal(),
                service_name: <WithErrorSyntaxMarker as fidl::endpoints::ServiceMarker>::DEBUG_NAME,
            }),
        }
    }
}
#[derive(Debug)]
pub enum WithErrorSyntaxRequest {
    ResponseAsStruct { responder: WithErrorSyntaxResponseAsStructResponder },
    ErrorAsPrimitive { responder: WithErrorSyntaxErrorAsPrimitiveResponder },
    ErrorAsEnum { responder: WithErrorSyntaxErrorAsEnumResponder },
}

impl WithErrorSyntaxRequest {
    #[allow(irrefutable_let_patterns)]
    pub fn into_response_as_struct(self) -> Option<(WithErrorSyntaxResponseAsStructResponder)> {
        if let WithErrorSyntaxRequest::ResponseAsStruct { responder } = self {
            Some((responder))
        } else {
            None
        }
    }

    #[allow(irrefutable_let_patterns)]
    pub fn into_error_as_primitive(self) -> Option<(WithErrorSyntaxErrorAsPrimitiveResponder)> {
        if let WithErrorSyntaxRequest::ErrorAsPrimitive { responder } = self {
            Some((responder))
        } else {
            None
        }
    }

    #[allow(irrefutable_let_patterns)]
    pub fn into_error_as_enum(self) -> Option<(WithErrorSyntaxErrorAsEnumResponder)> {
        if let WithErrorSyntaxRequest::ErrorAsEnum { responder } = self {
            Some((responder))
        } else {
            None
        }
    }

    /// Name of the method defined in FIDL
    pub fn method_name(&self) -> &'static str {
        match *self {
            WithErrorSyntaxRequest::ResponseAsStruct { .. } => "response_as_struct",
            WithErrorSyntaxRequest::ErrorAsPrimitive { .. } => "error_as_primitive",
            WithErrorSyntaxRequest::ErrorAsEnum { .. } => "error_as_enum",
        }
    }
}

pub struct WithErrorSyntaxEncoder;

impl WithErrorSyntaxEncoder {
    pub fn encode_response_as_struct_request<'a>(
        out_bytes: &'a mut Vec<u8>,
        out_handles: &'a mut Vec<fidl::HandleDisposition<'static>>,
        tx_id: u32,
    ) -> Result<(), fidl::Error> {
        let header = fidl::encoding::TransactionHeader::new(tx_id, 0x3784d38864674290);
        let mut body = ();
        let mut msg = fidl::encoding::TransactionMessage { header, body: &mut body };
        fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/WithErrorSyntaxResponseAsStructRequest");
        fidl::encoding::Encoder::encode(out_bytes, out_handles, &mut msg)?;
        fidl::trace_blob!("fidl:blob", "encode", out_bytes.as_slice());
        fidl::duration_end!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => out_bytes.len() as u32, "handle_count" => out_handles.len() as u32);
        Ok(())
    }
    pub fn encode_response_as_struct_response<'a>(
        out_bytes: &'a mut Vec<u8>,
        out_handles: &'a mut Vec<fidl::HandleDisposition<'static>>,
        tx_id: u32,
        mut in_result: &mut WithErrorSyntaxResponseAsStructResult,
    ) -> Result<(), fidl::Error> {
        let header = fidl::encoding::TransactionHeader::new(tx_id, 0x3784d38864674290);
        let mut body = (in_result,);
        let mut msg = fidl::encoding::TransactionMessage { header, body: &mut body };

        fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/WithErrorSyntaxResponseAsStructResponse");
        fidl::encoding::Encoder::encode(out_bytes, out_handles, &mut msg)?;
        fidl::trace_blob!("fidl:blob", "encode", out_bytes.as_slice());
        fidl::duration_end!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => out_bytes.len() as u32, "handle_count" => out_handles.len() as u32);

        Ok(())
    }
    pub fn encode_error_as_primitive_request<'a>(
        out_bytes: &'a mut Vec<u8>,
        out_handles: &'a mut Vec<fidl::HandleDisposition<'static>>,
        tx_id: u32,
    ) -> Result<(), fidl::Error> {
        let header = fidl::encoding::TransactionHeader::new(tx_id, 0x2f7c390f3cdef4ce);
        let mut body = ();
        let mut msg = fidl::encoding::TransactionMessage { header, body: &mut body };
        fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/WithErrorSyntaxErrorAsPrimitiveRequest");
        fidl::encoding::Encoder::encode(out_bytes, out_handles, &mut msg)?;
        fidl::trace_blob!("fidl:blob", "encode", out_bytes.as_slice());
        fidl::duration_end!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => out_bytes.len() as u32, "handle_count" => out_handles.len() as u32);
        Ok(())
    }
    pub fn encode_error_as_primitive_response<'a>(
        out_bytes: &'a mut Vec<u8>,
        out_handles: &'a mut Vec<fidl::HandleDisposition<'static>>,
        tx_id: u32,
        mut in_result: &mut WithErrorSyntaxErrorAsPrimitiveResult,
    ) -> Result<(), fidl::Error> {
        let header = fidl::encoding::TransactionHeader::new(tx_id, 0x2f7c390f3cdef4ce);
        let mut body = (in_result,);
        let mut msg = fidl::encoding::TransactionMessage { header, body: &mut body };

        fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/WithErrorSyntaxErrorAsPrimitiveResponse");
        fidl::encoding::Encoder::encode(out_bytes, out_handles, &mut msg)?;
        fidl::trace_blob!("fidl:blob", "encode", out_bytes.as_slice());
        fidl::duration_end!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => out_bytes.len() as u32, "handle_count" => out_handles.len() as u32);

        Ok(())
    }
    pub fn encode_error_as_enum_request<'a>(
        out_bytes: &'a mut Vec<u8>,
        out_handles: &'a mut Vec<fidl::HandleDisposition<'static>>,
        tx_id: u32,
    ) -> Result<(), fidl::Error> {
        let header = fidl::encoding::TransactionHeader::new(tx_id, 0x8b550d7c29f740c);
        let mut body = ();
        let mut msg = fidl::encoding::TransactionMessage { header, body: &mut body };
        fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/WithErrorSyntaxErrorAsEnumRequest");
        fidl::encoding::Encoder::encode(out_bytes, out_handles, &mut msg)?;
        fidl::trace_blob!("fidl:blob", "encode", out_bytes.as_slice());
        fidl::duration_end!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => out_bytes.len() as u32, "handle_count" => out_handles.len() as u32);
        Ok(())
    }
    pub fn encode_error_as_enum_response<'a>(
        out_bytes: &'a mut Vec<u8>,
        out_handles: &'a mut Vec<fidl::HandleDisposition<'static>>,
        tx_id: u32,
        mut in_result: &mut WithErrorSyntaxErrorAsEnumResult,
    ) -> Result<(), fidl::Error> {
        let header = fidl::encoding::TransactionHeader::new(tx_id, 0x8b550d7c29f740c);
        let mut body = (in_result,);
        let mut msg = fidl::encoding::TransactionMessage { header, body: &mut body };

        fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/WithErrorSyntaxErrorAsEnumResponse");
        fidl::encoding::Encoder::encode(out_bytes, out_handles, &mut msg)?;
        fidl::trace_blob!("fidl:blob", "encode", out_bytes.as_slice());
        fidl::duration_end!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => out_bytes.len() as u32, "handle_count" => out_handles.len() as u32);

        Ok(())
    }
}

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

impl WithErrorSyntaxControlHandle {
    /// Set the server to shutdown. The underlying channel is only closed the
    /// next time the stream is polled.
    pub fn shutdown(&self) {
        self.inner.shutdown()
    }

    pub fn shutdown_with_epitaph(&self, status: zx_status::Status) {
        self.inner.shutdown_with_epitaph(status)
    }
}
#[must_use = "FIDL methods require a response to be sent"]
#[derive(Debug)]
pub struct WithErrorSyntaxResponseAsStructResponder {
    control_handle: std::mem::ManuallyDrop<WithErrorSyntaxControlHandle>,
    tx_id: u32,
    ordinal: u64,
}

/// Set the the channel to be shutdown (see [`WithErrorSyntaxControlHandle::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 WithErrorSyntaxResponseAsStructResponder {
    fn drop(&mut self) {
        self.control_handle.shutdown();
        // Safety: drops once, never accessed again
        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
    }
}

impl WithErrorSyntaxResponseAsStructResponder {
    pub fn control_handle(&self) -> &WithErrorSyntaxControlHandle {
        &self.control_handle
    }

    /// Drop the Responder without setting the channel to shutdown.
    ///
    /// This method shouldn't normally be used-- instead, send a response
    /// to prevent the channel from shutting down.
    pub 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);
    }

    /// Sends a response to the FIDL transaction.
    ///
    /// Sets the channel to shutdown if an error occurs.
    pub fn send(
        self,
        mut result: &mut WithErrorSyntaxResponseAsStructResult,
    ) -> 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 WithErrorSyntaxResponseAsStructResult,
    ) -> Result<(), fidl::Error> {
        let r = self.send_raw(result);
        self.drop_without_shutdown();
        r
    }

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

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

        fidl::encoding::with_tls_encode_buf(|bytes, handles| {
            fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/WithErrorSyntaxResponseAsStructResponse");
            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 WithErrorSyntaxErrorAsPrimitiveResponder {
    control_handle: std::mem::ManuallyDrop<WithErrorSyntaxControlHandle>,
    tx_id: u32,
    ordinal: u64,
}

/// Set the the channel to be shutdown (see [`WithErrorSyntaxControlHandle::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 WithErrorSyntaxErrorAsPrimitiveResponder {
    fn drop(&mut self) {
        self.control_handle.shutdown();
        // Safety: drops once, never accessed again
        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
    }
}

impl WithErrorSyntaxErrorAsPrimitiveResponder {
    pub fn control_handle(&self) -> &WithErrorSyntaxControlHandle {
        &self.control_handle
    }

    /// Drop the Responder without setting the channel to shutdown.
    ///
    /// This method shouldn't normally be used-- instead, send a response
    /// to prevent the channel from shutting down.
    pub 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);
    }

    /// Sends a response to the FIDL transaction.
    ///
    /// Sets the channel to shutdown if an error occurs.
    pub fn send(
        self,
        mut result: &mut WithErrorSyntaxErrorAsPrimitiveResult,
    ) -> 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 WithErrorSyntaxErrorAsPrimitiveResult,
    ) -> Result<(), fidl::Error> {
        let r = self.send_raw(result);
        self.drop_without_shutdown();
        r
    }

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

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

        fidl::encoding::with_tls_encode_buf(|bytes, handles| {
            fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/WithErrorSyntaxErrorAsPrimitiveResponse");
            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 WithErrorSyntaxErrorAsEnumResponder {
    control_handle: std::mem::ManuallyDrop<WithErrorSyntaxControlHandle>,
    tx_id: u32,
    ordinal: u64,
}

/// Set the the channel to be shutdown (see [`WithErrorSyntaxControlHandle::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 WithErrorSyntaxErrorAsEnumResponder {
    fn drop(&mut self) {
        self.control_handle.shutdown();
        // Safety: drops once, never accessed again
        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
    }
}

impl WithErrorSyntaxErrorAsEnumResponder {
    pub fn control_handle(&self) -> &WithErrorSyntaxControlHandle {
        &self.control_handle
    }

    /// Drop the Responder without setting the channel to shutdown.
    ///
    /// This method shouldn't normally be used-- instead, send a response
    /// to prevent the channel from shutting down.
    pub 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);
    }

    /// Sends a response to the FIDL transaction.
    ///
    /// Sets the channel to shutdown if an error occurs.
    pub fn send(
        self,
        mut result: &mut WithErrorSyntaxErrorAsEnumResult,
    ) -> 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 WithErrorSyntaxErrorAsEnumResult,
    ) -> Result<(), fidl::Error> {
        let r = self.send_raw(result);
        self.drop_without_shutdown();
        r
    }

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

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

        fidl::encoding::with_tls_encode_buf(|bytes, handles| {
            fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/WithErrorSyntaxErrorAsEnumResponse");
            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(())
        })
    }
}

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

impl fidl::endpoints::ServiceMarker for ChannelProtocolMarker {
    type Proxy = ChannelProtocolProxy;
    type RequestStream = ChannelProtocolRequestStream;
    const DEBUG_NAME: &'static str = "(anonymous) ChannelProtocol";
}

pub trait ChannelProtocolProxyInterface: Send + Sync {
    fn r#method_a(&self, a: i64, b: i64) -> Result<(), fidl::Error>;
    type EventAResponseFut: std::future::Future<Output = Result<(i64, i64), fidl::Error>> + Send;
    type MethodBResponseFut: std::future::Future<Output = Result<(i64), fidl::Error>> + Send;
    fn r#method_b(&self, a: i64, b: i64) -> Self::MethodBResponseFut;
    type TakeHandleResponseFut: std::future::Future<Output = Result<(), fidl::Error>> + Send;
    fn r#take_handle(&self, h: fidl::Handle) -> Self::TakeHandleResponseFut;
    type MutateSocketResponseFut: std::future::Future<Output = Result<(fidl::Socket), fidl::Error>>
        + Send;
    fn r#mutate_socket(&self, a: fidl::Socket) -> Self::MutateSocketResponseFut;
}

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

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

    pub fn into_channel(self) -> fidl::Channel {
        self.client.into_channel()
    }
    pub fn r#method_a(&mut self, mut a: i64, mut b: i64) -> Result<(), fidl::Error> {
        self.client.send(&mut (a, b), 0x7d92c10fb2d002e)
    }
    pub fn r#method_b(
        &mut self,
        mut a: i64,
        mut b: i64,
        ___deadline: zx::Time,
    ) -> Result<(i64), fidl::Error> {
        let _value: (i64,) =
            self.client.send_query(&mut (a, b), 0x5da1d2ed00055cea, ___deadline)?;
        Ok(_value.0)
    }
    pub fn r#take_handle(
        &mut self,
        mut h: fidl::Handle,
        ___deadline: zx::Time,
    ) -> Result<(), fidl::Error> {
        let _value: () = self.client.send_query(&mut (h), 0xc25674355065c28, ___deadline)?;
        Ok(())
    }
    pub fn r#mutate_socket(
        &mut self,
        mut a: fidl::Socket,
        ___deadline: zx::Time,
    ) -> Result<(fidl::Socket), fidl::Error> {
        let _value: (HandleWrapperObjectTypeSOCKETRights2147483648<fidl::Socket>,) =
            self.client.send_query(&mut (a), 0x7dd036a18b33b76a, ___deadline)?;
        Ok(_value.0.into_inner())
    }
}

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

impl fidl::endpoints::Proxy for ChannelProtocolProxy {
    type Service = ChannelProtocolMarker;

    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 ChannelProtocolProxy {
    /// Create a new Proxy for ChannelProtocol
    pub fn new(channel: fidl::AsyncChannel) -> Self {
        let service_name = <ChannelProtocolMarker as fidl::endpoints::ServiceMarker>::DEBUG_NAME;
        Self { client: fidl::client::Client::new(channel, service_name) }
    }

    /// Get a Stream of events from the remote end of the ChannelProtocol protocol
    ///
    /// # Panics
    ///
    /// Panics if the event stream was already taken.
    pub fn take_event_stream(&self) -> ChannelProtocolEventStream {
        ChannelProtocolEventStream { event_receiver: self.client.take_event_receiver() }
    }
    pub fn r#method_a(&self, mut a: i64, mut b: i64) -> Result<(), fidl::Error> {
        ChannelProtocolProxyInterface::r#method_a(self, a, b)
    }
    pub fn r#method_b(&self, mut a: i64, mut b: i64) -> fidl::client::QueryResponseFut<(i64)> {
        ChannelProtocolProxyInterface::r#method_b(self, a, b)
    }
    pub fn r#take_handle(&self, mut h: fidl::Handle) -> fidl::client::QueryResponseFut<()> {
        ChannelProtocolProxyInterface::r#take_handle(self, h)
    }
    pub fn r#mutate_socket(
        &self,
        mut a: fidl::Socket,
    ) -> fidl::client::QueryResponseFut<(fidl::Socket)> {
        ChannelProtocolProxyInterface::r#mutate_socket(self, a)
    }
}

impl ChannelProtocolProxyInterface for ChannelProtocolProxy {
    fn r#method_a(&self, mut a: i64, mut b: i64) -> Result<(), fidl::Error> {
        self.client.send(&mut (a, b), 0x7d92c10fb2d002e)
    }
    type EventAResponseFut = fidl::client::QueryResponseFut<(i64, i64)>;
    type MethodBResponseFut = fidl::client::QueryResponseFut<(i64)>;
    fn r#method_b(&self, mut a: i64, mut b: i64) -> Self::MethodBResponseFut {
        fn transform(result: Result<(i64,), fidl::Error>) -> Result<(i64), fidl::Error> {
            result.map(|_value| _value.0)
        }
        let send_result = self.client.call_send_raw_query(&mut (a, b), 0x5da1d2ed00055cea);
        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 TakeHandleResponseFut = fidl::client::QueryResponseFut<()>;
    fn r#take_handle(&self, mut h: fidl::Handle) -> Self::TakeHandleResponseFut {
        fn transform(result: Result<(), fidl::Error>) -> Result<(), fidl::Error> {
            result.map(|_value| ())
        }
        let send_result = self.client.call_send_raw_query(&mut (h), 0xc25674355065c28);
        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 MutateSocketResponseFut = fidl::client::QueryResponseFut<(fidl::Socket)>;
    fn r#mutate_socket(&self, mut a: fidl::Socket) -> Self::MutateSocketResponseFut {
        fn transform(
            result: Result<
                (HandleWrapperObjectTypeSOCKETRights2147483648<fidl::Socket>,),
                fidl::Error,
            >,
        ) -> Result<(fidl::Socket), fidl::Error> {
            result.map(|_value| _value.0.into_inner())
        }
        let send_result = self.client.call_send_raw_query(&mut (a), 0x7dd036a18b33b76a);
        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)),
        })
    }
}

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

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

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

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

    fn poll_next(
        mut self: std::pin::Pin<&mut Self>,
        cx: &mut std::task::Context<'_>,
    ) -> std::task::Poll<Option<Self::Item>> {
        let mut 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),
        };
        let (bytes, _handles) = buf.split_mut();
        let (tx_header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;

        std::task::Poll::Ready(Some(match tx_header.ordinal() {
            0x52c2fa481a687dfa => {
                let mut out_tuple: (i64, i64) = fidl::encoding::Decodable::new_empty();
                fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/ChannelProtocolEventAEvent");
                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((ChannelProtocolEvent::EventA { a: out_tuple.0, b: out_tuple.1 }))
            }
            _ => Err(fidl::Error::UnknownOrdinal {
                ordinal: tx_header.ordinal(),
                service_name: <ChannelProtocolMarker as fidl::endpoints::ServiceMarker>::DEBUG_NAME,
            }),
        }))
    }
}

#[derive(Debug)]
pub enum ChannelProtocolEvent {
    EventA { a: i64, b: i64 },
}

impl ChannelProtocolEvent {
    #[allow(irrefutable_let_patterns)]
    pub fn into_event_a(self) -> Option<(i64, i64)> {
        if let ChannelProtocolEvent::EventA { a, b } = self {
            Some((a, b))
        } else {
            None
        }
    }
}

/// A type which can be used to send responses and events into a borrowed channel.
///
/// Note: this should only be used when the channel must be temporarily
/// borrowed. For a typical sending of events, use the send_ methods
/// on the ControlHandle types, which can be acquired through a
/// RequestStream or Responder type.
#[deprecated(note = "Use ChannelProtocolRequestStream / Responder instead")]
pub struct ChannelProtocolServerSender<'a> {
    // Some protocols don't define events which would render this channel unused.
    #[allow(dead_code)]
    channel: &'a fidl::Channel,
}

#[allow(deprecated)]
impl<'a> ChannelProtocolServerSender<'a> {
    pub fn new(channel: &'a fidl::Channel) -> Self {
        Self { channel }
    }
    pub fn send_event_a(&self, mut a: i64, mut b: i64) -> Result<(), fidl::Error> {
        fidl::encoding::with_tls_encode_buf(|bytes_, handles_| {
            ChannelProtocolEncoder::encode_event_a_response(bytes_, handles_, a, b)?;
            self.channel
                .write_etc(&*bytes_, &mut *handles_)
                .map_err(fidl::Error::ServerResponseWrite)?;
            Ok(())
        })
    }
    pub fn send_method_b_response(
        &self,
        txid: fidl::client::Txid,
        mut result: i64,
    ) -> Result<(), fidl::Error> {
        fidl::encoding::with_tls_encode_buf(|bytes_, handles_| {
            ChannelProtocolEncoder::encode_method_b_response(
                bytes_,
                handles_,
                txid.as_raw_id(),
                result,
            )?;
            self.channel
                .write_etc(&*bytes_, &mut *handles_)
                .map_err(fidl::Error::ServerResponseWrite)?;
            Ok(())
        })
    }
    pub fn send_take_handle_response(&self, txid: fidl::client::Txid) -> Result<(), fidl::Error> {
        fidl::encoding::with_tls_encode_buf(|bytes_, handles_| {
            ChannelProtocolEncoder::encode_take_handle_response(
                bytes_,
                handles_,
                txid.as_raw_id(),
            )?;
            self.channel
                .write_etc(&*bytes_, &mut *handles_)
                .map_err(fidl::Error::ServerResponseWrite)?;
            Ok(())
        })
    }
    pub fn send_mutate_socket_response(
        &self,
        txid: fidl::client::Txid,
        mut b: fidl::Socket,
    ) -> Result<(), fidl::Error> {
        fidl::encoding::with_tls_encode_buf(|bytes_, handles_| {
            ChannelProtocolEncoder::encode_mutate_socket_response(
                bytes_,
                handles_,
                txid.as_raw_id(),
                b,
            )?;
            self.channel
                .write_etc(&*bytes_, &mut *handles_)
                .map_err(fidl::Error::ServerResponseWrite)?;
            Ok(())
        })
    }
}

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

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

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

impl fidl::endpoints::RequestStream for ChannelProtocolRequestStream {
    type Service = ChannelProtocolMarker;

    /// Consume a channel to make a ChannelProtocolRequestStream
    fn from_channel(channel: fidl::AsyncChannel) -> Self {
        Self { inner: std::sync::Arc::new(fidl::ServeInner::new(channel)), is_terminated: false }
    }

    /// ControlHandle for the remote connection
    type ControlHandle = ChannelProtocolControlHandle;

    /// ControlHandle for the remote connection
    fn control_handle(&self) -> Self::ControlHandle {
        ChannelProtocolControlHandle { 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 ChannelProtocolRequestStream {
    type Item = Result<ChannelProtocolRequest, 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 ChannelProtocolRequestStream 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() {
                0x7d92c10fb2d002e => {
                    let mut req: (i64, i64) = fidl::encoding::Decodable::new_empty();
                    fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/ChannelProtocolMethodARequest");
                    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 = ChannelProtocolControlHandle { inner: this.inner.clone() };

                    Ok(ChannelProtocolRequest::MethodA { a: req.0, b: req.1, control_handle })
                }
                0x5da1d2ed00055cea => {
                    let mut req: (i64, i64) = fidl::encoding::Decodable::new_empty();
                    fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/ChannelProtocolMethodBRequest");
                    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 = ChannelProtocolControlHandle { inner: this.inner.clone() };

                    Ok(ChannelProtocolRequest::MethodB {
                        a: req.0,
                        b: req.1,
                        responder: ChannelProtocolMethodBResponder {
                            control_handle: std::mem::ManuallyDrop::new(control_handle),
                            tx_id: header.tx_id(),
                            ordinal: header.ordinal(),
                        },
                    })
                }
                0xc25674355065c28 => {
                    let mut req: (HandleWrapperObjectTypeNONERights2147483648<fidl::Handle>,) =
                        fidl::encoding::Decodable::new_empty();
                    fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/ChannelProtocolTakeHandleRequest");
                    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 = ChannelProtocolControlHandle { inner: this.inner.clone() };

                    Ok(ChannelProtocolRequest::TakeHandle {
                        h: req.0.into_inner(),
                        responder: ChannelProtocolTakeHandleResponder {
                            control_handle: std::mem::ManuallyDrop::new(control_handle),
                            tx_id: header.tx_id(),
                            ordinal: header.ordinal(),
                        },
                    })
                }
                0x7dd036a18b33b76a => {
                    let mut req: (HandleWrapperObjectTypeSOCKETRights2147483648<fidl::Socket>,) =
                        fidl::encoding::Decodable::new_empty();
                    fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/ChannelProtocolMutateSocketRequest");
                    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 = ChannelProtocolControlHandle { inner: this.inner.clone() };

                    Ok(ChannelProtocolRequest::MutateSocket {
                        a: req.0.into_inner(),
                        responder: ChannelProtocolMutateSocketResponder {
                            control_handle: std::mem::ManuallyDrop::new(control_handle),
                            tx_id: header.tx_id(),
                            ordinal: header.ordinal(),
                        },
                    })
                }
                _ => Err(fidl::Error::UnknownOrdinal {
                    ordinal: header.ordinal(),
                    service_name:
                        <ChannelProtocolMarker as fidl::endpoints::ServiceMarker>::DEBUG_NAME,
                }),
            }))
        })
    }
}

/// Represents a single request.
/// RequestMessages should only be used for manual deserialization when higher level
/// structs such as RequestStream cannot be used. One usually would only encounter
/// such scenarios when working with legacy FIDL code (prior to FIDL generated client/server bindings).
#[derive(Debug)]
#[deprecated(note = "Use ChannelProtocolRequest instead")]
pub enum ChannelProtocolRequestMessage {
    MethodA { a: i64, b: i64 },
    MethodB { a: i64, b: i64, tx_id: fidl::client::Txid },
    TakeHandle { h: fidl::Handle, tx_id: fidl::client::Txid },
    MutateSocket { a: fidl::Socket, tx_id: fidl::client::Txid },
}

#[allow(deprecated)]
impl ChannelProtocolRequestMessage {
    pub fn decode(
        bytes: &[u8],
        _handles: &mut [fidl::HandleInfo],
    ) -> Result<ChannelProtocolRequestMessage, fidl::Error> {
        let (header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;

        match header.ordinal() {
            0x7d92c10fb2d002e => {
                let mut out_tuple: (i64, i64) = fidl::encoding::Decodable::new_empty();
                fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/ChannelProtocolMethodARequest");
                fidl::trace_blob!("fidl:blob", "decode", bytes);
                fidl::encoding::Decoder::decode_into(
                    &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(ChannelProtocolRequestMessage::MethodA { a: out_tuple.0, b: out_tuple.1 })
            }
            0x5da1d2ed00055cea => {
                let mut out_tuple: (i64, i64) = fidl::encoding::Decodable::new_empty();
                fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/ChannelProtocolMethodBRequest");
                fidl::trace_blob!("fidl:blob", "decode", bytes);
                fidl::encoding::Decoder::decode_into(
                    &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(ChannelProtocolRequestMessage::MethodB {
                    a: out_tuple.0,
                    b: out_tuple.1,
                    tx_id: header.tx_id().into(),
                })
            }
            0xc25674355065c28 => {
                let mut out_tuple: (HandleWrapperObjectTypeNONERights2147483648<fidl::Handle>,) =
                    fidl::encoding::Decodable::new_empty();
                fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/ChannelProtocolTakeHandleRequest");
                fidl::trace_blob!("fidl:blob", "decode", bytes);
                fidl::encoding::Decoder::decode_into(
                    &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(ChannelProtocolRequestMessage::TakeHandle {
                    h: out_tuple.0.into_inner(),
                    tx_id: header.tx_id().into(),
                })
            }
            0x7dd036a18b33b76a => {
                let mut out_tuple: (HandleWrapperObjectTypeSOCKETRights2147483648<fidl::Socket>,) =
                    fidl::encoding::Decodable::new_empty();
                fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/ChannelProtocolMutateSocketRequest");
                fidl::trace_blob!("fidl:blob", "decode", bytes);
                fidl::encoding::Decoder::decode_into(
                    &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(ChannelProtocolRequestMessage::MutateSocket {
                    a: out_tuple.0.into_inner(),
                    tx_id: header.tx_id().into(),
                })
            }
            _ => Err(fidl::Error::UnknownOrdinal {
                ordinal: header.ordinal(),
                service_name: <ChannelProtocolMarker as fidl::endpoints::ServiceMarker>::DEBUG_NAME,
            }),
        }
    }
}
#[derive(Debug)]
pub enum ChannelProtocolRequest {
    MethodA { a: i64, b: i64, control_handle: ChannelProtocolControlHandle },
    MethodB { a: i64, b: i64, responder: ChannelProtocolMethodBResponder },
    TakeHandle { h: fidl::Handle, responder: ChannelProtocolTakeHandleResponder },
    MutateSocket { a: fidl::Socket, responder: ChannelProtocolMutateSocketResponder },
}

impl ChannelProtocolRequest {
    #[allow(irrefutable_let_patterns)]
    pub fn into_method_a(self) -> Option<(i64, i64, ChannelProtocolControlHandle)> {
        if let ChannelProtocolRequest::MethodA { a, b, control_handle } = self {
            Some((a, b, control_handle))
        } else {
            None
        }
    }

    #[allow(irrefutable_let_patterns)]
    pub fn into_method_b(self) -> Option<(i64, i64, ChannelProtocolMethodBResponder)> {
        if let ChannelProtocolRequest::MethodB { a, b, responder } = self {
            Some((a, b, responder))
        } else {
            None
        }
    }

    #[allow(irrefutable_let_patterns)]
    pub fn into_take_handle(self) -> Option<(fidl::Handle, ChannelProtocolTakeHandleResponder)> {
        if let ChannelProtocolRequest::TakeHandle { h, responder } = self {
            Some((h, responder))
        } else {
            None
        }
    }

    #[allow(irrefutable_let_patterns)]
    pub fn into_mutate_socket(
        self,
    ) -> Option<(fidl::Socket, ChannelProtocolMutateSocketResponder)> {
        if let ChannelProtocolRequest::MutateSocket { a, responder } = self {
            Some((a, responder))
        } else {
            None
        }
    }

    /// Name of the method defined in FIDL
    pub fn method_name(&self) -> &'static str {
        match *self {
            ChannelProtocolRequest::MethodA { .. } => "method_a",
            ChannelProtocolRequest::MethodB { .. } => "method_b",
            ChannelProtocolRequest::TakeHandle { .. } => "take_handle",
            ChannelProtocolRequest::MutateSocket { .. } => "mutate_socket",
        }
    }
}

pub struct ChannelProtocolEncoder;

impl ChannelProtocolEncoder {
    pub fn encode_method_a_request<'a>(
        out_bytes: &'a mut Vec<u8>,
        out_handles: &'a mut Vec<fidl::HandleDisposition<'static>>,
        mut in_a: i64,
        mut in_b: i64,
    ) -> Result<(), fidl::Error> {
        let header = fidl::encoding::TransactionHeader::new(0, 0x7d92c10fb2d002e);
        let mut body = (in_a, in_b);
        let mut msg = fidl::encoding::TransactionMessage { header, body: &mut body };
        fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/ChannelProtocolMethodARequest");
        fidl::encoding::Encoder::encode(out_bytes, out_handles, &mut msg)?;
        fidl::trace_blob!("fidl:blob", "encode", out_bytes.as_slice());
        fidl::duration_end!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => out_bytes.len() as u32, "handle_count" => out_handles.len() as u32);
        Ok(())
    }
    pub fn encode_event_a_response<'a>(
        out_bytes: &'a mut Vec<u8>,
        out_handles: &'a mut Vec<fidl::HandleDisposition<'static>>,
        mut in_a: i64,
        mut in_b: i64,
    ) -> Result<(), fidl::Error> {
        let header = fidl::encoding::TransactionHeader::new(0, 0x52c2fa481a687dfa);
        let mut body = (in_a, in_b);
        let mut msg = fidl::encoding::TransactionMessage { header, body: &mut body };

        fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/ChannelProtocolEventAResponse");
        fidl::encoding::Encoder::encode(out_bytes, out_handles, &mut msg)?;
        fidl::trace_blob!("fidl:blob", "encode", out_bytes.as_slice());
        fidl::duration_end!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => out_bytes.len() as u32, "handle_count" => out_handles.len() as u32);

        Ok(())
    }
    pub fn encode_method_b_request<'a>(
        out_bytes: &'a mut Vec<u8>,
        out_handles: &'a mut Vec<fidl::HandleDisposition<'static>>,
        tx_id: u32,
        mut in_a: i64,
        mut in_b: i64,
    ) -> Result<(), fidl::Error> {
        let header = fidl::encoding::TransactionHeader::new(tx_id, 0x5da1d2ed00055cea);
        let mut body = (in_a, in_b);
        let mut msg = fidl::encoding::TransactionMessage { header, body: &mut body };
        fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/ChannelProtocolMethodBRequest");
        fidl::encoding::Encoder::encode(out_bytes, out_handles, &mut msg)?;
        fidl::trace_blob!("fidl:blob", "encode", out_bytes.as_slice());
        fidl::duration_end!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => out_bytes.len() as u32, "handle_count" => out_handles.len() as u32);
        Ok(())
    }
    pub fn encode_method_b_response<'a>(
        out_bytes: &'a mut Vec<u8>,
        out_handles: &'a mut Vec<fidl::HandleDisposition<'static>>,
        tx_id: u32,
        mut in_result: i64,
    ) -> Result<(), fidl::Error> {
        let header = fidl::encoding::TransactionHeader::new(tx_id, 0x5da1d2ed00055cea);
        let mut body = (in_result,);
        let mut msg = fidl::encoding::TransactionMessage { header, body: &mut body };

        fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/ChannelProtocolMethodBResponse");
        fidl::encoding::Encoder::encode(out_bytes, out_handles, &mut msg)?;
        fidl::trace_blob!("fidl:blob", "encode", out_bytes.as_slice());
        fidl::duration_end!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => out_bytes.len() as u32, "handle_count" => out_handles.len() as u32);

        Ok(())
    }
    pub fn encode_take_handle_request<'a>(
        out_bytes: &'a mut Vec<u8>,
        out_handles: &'a mut Vec<fidl::HandleDisposition<'static>>,
        tx_id: u32,
        mut in_h: fidl::Handle,
    ) -> Result<(), fidl::Error> {
        let header = fidl::encoding::TransactionHeader::new(tx_id, 0xc25674355065c28);
        let mut body = (in_h,);
        let mut msg = fidl::encoding::TransactionMessage { header, body: &mut body };
        fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/ChannelProtocolTakeHandleRequest");
        fidl::encoding::Encoder::encode(out_bytes, out_handles, &mut msg)?;
        fidl::trace_blob!("fidl:blob", "encode", out_bytes.as_slice());
        fidl::duration_end!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => out_bytes.len() as u32, "handle_count" => out_handles.len() as u32);
        Ok(())
    }
    pub fn encode_take_handle_response<'a>(
        out_bytes: &'a mut Vec<u8>,
        out_handles: &'a mut Vec<fidl::HandleDisposition<'static>>,
        tx_id: u32,
    ) -> Result<(), fidl::Error> {
        let header = fidl::encoding::TransactionHeader::new(tx_id, 0xc25674355065c28);
        let mut body = ();
        let mut msg = fidl::encoding::TransactionMessage { header, body: &mut body };

        fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/ChannelProtocolTakeHandleResponse");
        fidl::encoding::Encoder::encode(out_bytes, out_handles, &mut msg)?;
        fidl::trace_blob!("fidl:blob", "encode", out_bytes.as_slice());
        fidl::duration_end!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => out_bytes.len() as u32, "handle_count" => out_handles.len() as u32);

        Ok(())
    }
    pub fn encode_mutate_socket_request<'a>(
        out_bytes: &'a mut Vec<u8>,
        out_handles: &'a mut Vec<fidl::HandleDisposition<'static>>,
        tx_id: u32,
        mut in_a: fidl::Socket,
    ) -> Result<(), fidl::Error> {
        let header = fidl::encoding::TransactionHeader::new(tx_id, 0x7dd036a18b33b76a);
        let mut body = (in_a,);
        let mut msg = fidl::encoding::TransactionMessage { header, body: &mut body };
        fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/ChannelProtocolMutateSocketRequest");
        fidl::encoding::Encoder::encode(out_bytes, out_handles, &mut msg)?;
        fidl::trace_blob!("fidl:blob", "encode", out_bytes.as_slice());
        fidl::duration_end!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => out_bytes.len() as u32, "handle_count" => out_handles.len() as u32);
        Ok(())
    }
    pub fn encode_mutate_socket_response<'a>(
        out_bytes: &'a mut Vec<u8>,
        out_handles: &'a mut Vec<fidl::HandleDisposition<'static>>,
        tx_id: u32,
        mut in_b: fidl::Socket,
    ) -> Result<(), fidl::Error> {
        let header = fidl::encoding::TransactionHeader::new(tx_id, 0x7dd036a18b33b76a);
        let mut body = (in_b,);
        let mut msg = fidl::encoding::TransactionMessage { header, body: &mut body };

        fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/ChannelProtocolMutateSocketResponse");
        fidl::encoding::Encoder::encode(out_bytes, out_handles, &mut msg)?;
        fidl::trace_blob!("fidl:blob", "encode", out_bytes.as_slice());
        fidl::duration_end!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => out_bytes.len() as u32, "handle_count" => out_handles.len() as u32);

        Ok(())
    }
}

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

impl ChannelProtocolControlHandle {
    /// Set the server to shutdown. The underlying channel is only closed the
    /// next time the stream is polled.
    pub fn shutdown(&self) {
        self.inner.shutdown()
    }

    pub fn shutdown_with_epitaph(&self, status: zx_status::Status) {
        self.inner.shutdown_with_epitaph(status)
    }
    pub fn send_event_a(&self, mut a: i64, mut b: i64) -> Result<(), fidl::Error> {
        let mut response = (a, b);

        let mut msg = fidl::encoding::TransactionMessage {
            header: fidl::encoding::TransactionHeader::new(0, 0x52c2fa481a687dfa),
            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 ChannelProtocolMethodBResponder {
    control_handle: std::mem::ManuallyDrop<ChannelProtocolControlHandle>,
    tx_id: u32,
    ordinal: u64,
}

/// Set the the channel to be shutdown (see [`ChannelProtocolControlHandle::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 ChannelProtocolMethodBResponder {
    fn drop(&mut self) {
        self.control_handle.shutdown();
        // Safety: drops once, never accessed again
        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
    }
}

impl ChannelProtocolMethodBResponder {
    pub fn control_handle(&self) -> &ChannelProtocolControlHandle {
        &self.control_handle
    }

    /// Drop the Responder without setting the channel to shutdown.
    ///
    /// This method shouldn't normally be used-- instead, send a response
    /// to prevent the channel from shutting down.
    pub 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);
    }

    /// Sends a response to the FIDL transaction.
    ///
    /// Sets the channel to shutdown if an error occurs.
    pub fn send(self, mut result: i64) -> 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: i64) -> Result<(), fidl::Error> {
        let r = self.send_raw(result);
        self.drop_without_shutdown();
        r
    }

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

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

        fidl::encoding::with_tls_encode_buf(|bytes, handles| {
            fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/ChannelProtocolMethodBResponse");
            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 ChannelProtocolTakeHandleResponder {
    control_handle: std::mem::ManuallyDrop<ChannelProtocolControlHandle>,
    tx_id: u32,
    ordinal: u64,
}

/// Set the the channel to be shutdown (see [`ChannelProtocolControlHandle::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 ChannelProtocolTakeHandleResponder {
    fn drop(&mut self) {
        self.control_handle.shutdown();
        // Safety: drops once, never accessed again
        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
    }
}

impl ChannelProtocolTakeHandleResponder {
    pub fn control_handle(&self) -> &ChannelProtocolControlHandle {
        &self.control_handle
    }

    /// Drop the Responder without setting the channel to shutdown.
    ///
    /// This method shouldn't normally be used-- instead, send a response
    /// to prevent the channel from shutting down.
    pub 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);
    }

    /// Sends a response to the FIDL transaction.
    ///
    /// Sets the channel to shutdown if an error occurs.
    pub fn send(self) -> Result<(), fidl::Error> {
        let r = self.send_raw();
        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) -> Result<(), fidl::Error> {
        let r = self.send_raw();
        self.drop_without_shutdown();
        r
    }

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

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

        fidl::encoding::with_tls_encode_buf(|bytes, handles| {
            fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/ChannelProtocolTakeHandleResponse");
            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 ChannelProtocolMutateSocketResponder {
    control_handle: std::mem::ManuallyDrop<ChannelProtocolControlHandle>,
    tx_id: u32,
    ordinal: u64,
}

/// Set the the channel to be shutdown (see [`ChannelProtocolControlHandle::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 ChannelProtocolMutateSocketResponder {
    fn drop(&mut self) {
        self.control_handle.shutdown();
        // Safety: drops once, never accessed again
        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
    }
}

impl ChannelProtocolMutateSocketResponder {
    pub fn control_handle(&self) -> &ChannelProtocolControlHandle {
        &self.control_handle
    }

    /// Drop the Responder without setting the channel to shutdown.
    ///
    /// This method shouldn't normally be used-- instead, send a response
    /// to prevent the channel from shutting down.
    pub 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);
    }

    /// Sends a response to the FIDL transaction.
    ///
    /// Sets the channel to shutdown if an error occurs.
    pub fn send(self, mut b: fidl::Socket) -> Result<(), fidl::Error> {
        let r = self.send_raw(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 b: fidl::Socket) -> Result<(), fidl::Error> {
        let r = self.send_raw(b);
        self.drop_without_shutdown();
        r
    }

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

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

        fidl::encoding::with_tls_encode_buf(|bytes, handles| {
            fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/ChannelProtocolMutateSocketResponse");
            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(())
        })
    }
}

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

impl fidl::endpoints::ServiceMarker for TransitionalMarker {
    type Proxy = TransitionalProxy;
    type RequestStream = TransitionalRequestStream;
    const DEBUG_NAME: &'static str = "(anonymous) Transitional";
}

pub trait TransitionalProxyInterface: Send + Sync {
    type RequestResponseFut: std::future::Future<Output = Result<(i64), fidl::Error>> + Send;
    #[allow(unused_variables)]
    fn r#request(&self, x: i64) -> Self::RequestResponseFut {
        unimplemented!("transitional method request is unimplemented");
    }
    #[allow(unused_variables)]
    fn r#one_way(&self, x: i64) -> Result<(), fidl::Error> {
        unimplemented!("transitional method one_way is unimplemented");
    }
    type EventResponseFut: std::future::Future<Output = Result<(i64), fidl::Error>> + Send;
}

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

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

    pub fn into_channel(self) -> fidl::Channel {
        self.client.into_channel()
    }
    pub fn r#request(&mut self, mut x: i64, ___deadline: zx::Time) -> Result<(i64), fidl::Error> {
        let _value: (i64,) = self.client.send_query(&mut (x), 0x62d345e621780ee8, ___deadline)?;
        Ok(_value.0)
    }
    pub fn r#one_way(&mut self, mut x: i64) -> Result<(), fidl::Error> {
        self.client.send(&mut (x), 0xf99bc4b26bc9ea5)
    }
}

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

impl fidl::endpoints::Proxy for TransitionalProxy {
    type Service = TransitionalMarker;

    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 TransitionalProxy {
    /// Create a new Proxy for Transitional
    pub fn new(channel: fidl::AsyncChannel) -> Self {
        let service_name = <TransitionalMarker as fidl::endpoints::ServiceMarker>::DEBUG_NAME;
        Self { client: fidl::client::Client::new(channel, service_name) }
    }

    /// Get a Stream of events from the remote end of the Transitional protocol
    ///
    /// # Panics
    ///
    /// Panics if the event stream was already taken.
    pub fn take_event_stream(&self) -> TransitionalEventStream {
        TransitionalEventStream { event_receiver: self.client.take_event_receiver() }
    }
    pub fn r#request(&self, mut x: i64) -> fidl::client::QueryResponseFut<(i64)> {
        TransitionalProxyInterface::r#request(self, x)
    }
    pub fn r#one_way(&self, mut x: i64) -> Result<(), fidl::Error> {
        TransitionalProxyInterface::r#one_way(self, x)
    }
}

impl TransitionalProxyInterface for TransitionalProxy {
    type RequestResponseFut = fidl::client::QueryResponseFut<(i64)>;
    fn r#request(&self, mut x: i64) -> Self::RequestResponseFut {
        fn transform(result: Result<(i64,), fidl::Error>) -> Result<(i64), fidl::Error> {
            result.map(|_value| _value.0)
        }
        let send_result = self.client.call_send_raw_query(&mut (x), 0x62d345e621780ee8);
        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)),
        })
    }
    fn r#one_way(&self, mut x: i64) -> Result<(), fidl::Error> {
        self.client.send(&mut (x), 0xf99bc4b26bc9ea5)
    }
    type EventResponseFut = fidl::client::QueryResponseFut<(i64)>;
}

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

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

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

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

    fn poll_next(
        mut self: std::pin::Pin<&mut Self>,
        cx: &mut std::task::Context<'_>,
    ) -> std::task::Poll<Option<Self::Item>> {
        let mut 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),
        };
        let (bytes, _handles) = buf.split_mut();
        let (tx_header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;

        std::task::Poll::Ready(Some(match tx_header.ordinal() {
            0x53bb9212bcbe8966 => {
                let mut out_tuple: (i64,) = fidl::encoding::Decodable::new_empty();
                fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/TransitionalEventEvent");
                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((TransitionalEvent::Event { x: out_tuple.0 }))
            }
            _ => Err(fidl::Error::UnknownOrdinal {
                ordinal: tx_header.ordinal(),
                service_name: <TransitionalMarker as fidl::endpoints::ServiceMarker>::DEBUG_NAME,
            }),
        }))
    }
}

#[derive(Debug)]
pub enum TransitionalEvent {
    Event { x: i64 },
}

impl TransitionalEvent {
    #[allow(irrefutable_let_patterns)]
    pub fn into_event(self) -> Option<(i64)> {
        if let TransitionalEvent::Event { x } = self {
            Some((x))
        } else {
            None
        }
    }
}

/// A type which can be used to send responses and events into a borrowed channel.
///
/// Note: this should only be used when the channel must be temporarily
/// borrowed. For a typical sending of events, use the send_ methods
/// on the ControlHandle types, which can be acquired through a
/// RequestStream or Responder type.
#[deprecated(note = "Use TransitionalRequestStream / Responder instead")]
pub struct TransitionalServerSender<'a> {
    // Some protocols don't define events which would render this channel unused.
    #[allow(dead_code)]
    channel: &'a fidl::Channel,
}

#[allow(deprecated)]
impl<'a> TransitionalServerSender<'a> {
    pub fn new(channel: &'a fidl::Channel) -> Self {
        Self { channel }
    }
    pub fn send_request_response(
        &self,
        txid: fidl::client::Txid,
        mut y: i64,
    ) -> Result<(), fidl::Error> {
        fidl::encoding::with_tls_encode_buf(|bytes_, handles_| {
            TransitionalEncoder::encode_request_response(bytes_, handles_, txid.as_raw_id(), y)?;
            self.channel
                .write_etc(&*bytes_, &mut *handles_)
                .map_err(fidl::Error::ServerResponseWrite)?;
            Ok(())
        })
    }
    pub fn send_event(&self, mut x: i64) -> Result<(), fidl::Error> {
        fidl::encoding::with_tls_encode_buf(|bytes_, handles_| {
            TransitionalEncoder::encode_event_response(bytes_, handles_, x)?;
            self.channel
                .write_etc(&*bytes_, &mut *handles_)
                .map_err(fidl::Error::ServerResponseWrite)?;
            Ok(())
        })
    }
}

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

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

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

impl fidl::endpoints::RequestStream for TransitionalRequestStream {
    type Service = TransitionalMarker;

    /// Consume a channel to make a TransitionalRequestStream
    fn from_channel(channel: fidl::AsyncChannel) -> Self {
        Self { inner: std::sync::Arc::new(fidl::ServeInner::new(channel)), is_terminated: false }
    }

    /// ControlHandle for the remote connection
    type ControlHandle = TransitionalControlHandle;

    /// ControlHandle for the remote connection
    fn control_handle(&self) -> Self::ControlHandle {
        TransitionalControlHandle { 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 TransitionalRequestStream {
    type Item = Result<TransitionalRequest, 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 TransitionalRequestStream 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() {
                0x62d345e621780ee8 => {
                    let mut req: (i64,) = fidl::encoding::Decodable::new_empty();
                    fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/TransitionalRequestRequest");
                    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 = TransitionalControlHandle { inner: this.inner.clone() };

                    Ok(TransitionalRequest::Request {
                        x: req.0,
                        responder: TransitionalRequestResponder {
                            control_handle: std::mem::ManuallyDrop::new(control_handle),
                            tx_id: header.tx_id(),
                            ordinal: header.ordinal(),
                        },
                    })
                }
                0xf99bc4b26bc9ea5 => {
                    let mut req: (i64,) = fidl::encoding::Decodable::new_empty();
                    fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/TransitionalOneWayRequest");
                    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 = TransitionalControlHandle { inner: this.inner.clone() };

                    Ok(TransitionalRequest::OneWay { x: req.0, control_handle })
                }
                _ => Err(fidl::Error::UnknownOrdinal {
                    ordinal: header.ordinal(),
                    service_name:
                        <TransitionalMarker as fidl::endpoints::ServiceMarker>::DEBUG_NAME,
                }),
            }))
        })
    }
}

/// Represents a single request.
/// RequestMessages should only be used for manual deserialization when higher level
/// structs such as RequestStream cannot be used. One usually would only encounter
/// such scenarios when working with legacy FIDL code (prior to FIDL generated client/server bindings).
#[derive(Debug)]
#[deprecated(note = "Use TransitionalRequest instead")]
pub enum TransitionalRequestMessage {
    Request { x: i64, tx_id: fidl::client::Txid },
    OneWay { x: i64 },
}

#[allow(deprecated)]
impl TransitionalRequestMessage {
    pub fn decode(
        bytes: &[u8],
        _handles: &mut [fidl::HandleInfo],
    ) -> Result<TransitionalRequestMessage, fidl::Error> {
        let (header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;

        match header.ordinal() {
            0x62d345e621780ee8 => {
                let mut out_tuple: (i64,) = fidl::encoding::Decodable::new_empty();
                fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/TransitionalRequestRequest");
                fidl::trace_blob!("fidl:blob", "decode", bytes);
                fidl::encoding::Decoder::decode_into(
                    &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(TransitionalRequestMessage::Request {
                    x: out_tuple.0,
                    tx_id: header.tx_id().into(),
                })
            }
            0xf99bc4b26bc9ea5 => {
                let mut out_tuple: (i64,) = fidl::encoding::Decodable::new_empty();
                fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/TransitionalOneWayRequest");
                fidl::trace_blob!("fidl:blob", "decode", bytes);
                fidl::encoding::Decoder::decode_into(
                    &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(TransitionalRequestMessage::OneWay { x: out_tuple.0 })
            }
            _ => Err(fidl::Error::UnknownOrdinal {
                ordinal: header.ordinal(),
                service_name: <TransitionalMarker as fidl::endpoints::ServiceMarker>::DEBUG_NAME,
            }),
        }
    }
}
#[derive(Debug)]
pub enum TransitionalRequest {
    Request { x: i64, responder: TransitionalRequestResponder },
    OneWay { x: i64, control_handle: TransitionalControlHandle },
}

impl TransitionalRequest {
    #[allow(irrefutable_let_patterns)]
    pub fn into_request(self) -> Option<(i64, TransitionalRequestResponder)> {
        if let TransitionalRequest::Request { x, responder } = self {
            Some((x, responder))
        } else {
            None
        }
    }

    #[allow(irrefutable_let_patterns)]
    pub fn into_one_way(self) -> Option<(i64, TransitionalControlHandle)> {
        if let TransitionalRequest::OneWay { x, control_handle } = self {
            Some((x, control_handle))
        } else {
            None
        }
    }

    /// Name of the method defined in FIDL
    pub fn method_name(&self) -> &'static str {
        match *self {
            TransitionalRequest::Request { .. } => "request",
            TransitionalRequest::OneWay { .. } => "one_way",
        }
    }
}

pub struct TransitionalEncoder;

impl TransitionalEncoder {
    pub fn encode_request_request<'a>(
        out_bytes: &'a mut Vec<u8>,
        out_handles: &'a mut Vec<fidl::HandleDisposition<'static>>,
        tx_id: u32,
        mut in_x: i64,
    ) -> Result<(), fidl::Error> {
        let header = fidl::encoding::TransactionHeader::new(tx_id, 0x62d345e621780ee8);
        let mut body = (in_x,);
        let mut msg = fidl::encoding::TransactionMessage { header, body: &mut body };
        fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/TransitionalRequestRequest");
        fidl::encoding::Encoder::encode(out_bytes, out_handles, &mut msg)?;
        fidl::trace_blob!("fidl:blob", "encode", out_bytes.as_slice());
        fidl::duration_end!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => out_bytes.len() as u32, "handle_count" => out_handles.len() as u32);
        Ok(())
    }
    pub fn encode_request_response<'a>(
        out_bytes: &'a mut Vec<u8>,
        out_handles: &'a mut Vec<fidl::HandleDisposition<'static>>,
        tx_id: u32,
        mut in_y: i64,
    ) -> Result<(), fidl::Error> {
        let header = fidl::encoding::TransactionHeader::new(tx_id, 0x62d345e621780ee8);
        let mut body = (in_y,);
        let mut msg = fidl::encoding::TransactionMessage { header, body: &mut body };

        fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/TransitionalRequestResponse");
        fidl::encoding::Encoder::encode(out_bytes, out_handles, &mut msg)?;
        fidl::trace_blob!("fidl:blob", "encode", out_bytes.as_slice());
        fidl::duration_end!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => out_bytes.len() as u32, "handle_count" => out_handles.len() as u32);

        Ok(())
    }
    pub fn encode_one_way_request<'a>(
        out_bytes: &'a mut Vec<u8>,
        out_handles: &'a mut Vec<fidl::HandleDisposition<'static>>,
        mut in_x: i64,
    ) -> Result<(), fidl::Error> {
        let header = fidl::encoding::TransactionHeader::new(0, 0xf99bc4b26bc9ea5);
        let mut body = (in_x,);
        let mut msg = fidl::encoding::TransactionMessage { header, body: &mut body };
        fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/TransitionalOneWayRequest");
        fidl::encoding::Encoder::encode(out_bytes, out_handles, &mut msg)?;
        fidl::trace_blob!("fidl:blob", "encode", out_bytes.as_slice());
        fidl::duration_end!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => out_bytes.len() as u32, "handle_count" => out_handles.len() as u32);
        Ok(())
    }
    pub fn encode_event_response<'a>(
        out_bytes: &'a mut Vec<u8>,
        out_handles: &'a mut Vec<fidl::HandleDisposition<'static>>,
        mut in_x: i64,
    ) -> Result<(), fidl::Error> {
        let header = fidl::encoding::TransactionHeader::new(0, 0x53bb9212bcbe8966);
        let mut body = (in_x,);
        let mut msg = fidl::encoding::TransactionMessage { header, body: &mut body };

        fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/TransitionalEventResponse");
        fidl::encoding::Encoder::encode(out_bytes, out_handles, &mut msg)?;
        fidl::trace_blob!("fidl:blob", "encode", out_bytes.as_slice());
        fidl::duration_end!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => out_bytes.len() as u32, "handle_count" => out_handles.len() as u32);

        Ok(())
    }
}

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

impl TransitionalControlHandle {
    /// Set the server to shutdown. The underlying channel is only closed the
    /// next time the stream is polled.
    pub fn shutdown(&self) {
        self.inner.shutdown()
    }

    pub fn shutdown_with_epitaph(&self, status: zx_status::Status) {
        self.inner.shutdown_with_epitaph(status)
    }
    pub fn send_event(&self, mut x: i64) -> Result<(), fidl::Error> {
        let mut response = (x);

        let mut msg = fidl::encoding::TransactionMessage {
            header: fidl::encoding::TransactionHeader::new(0, 0x53bb9212bcbe8966),
            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 TransitionalRequestResponder {
    control_handle: std::mem::ManuallyDrop<TransitionalControlHandle>,
    tx_id: u32,
    ordinal: u64,
}

/// Set the the channel to be shutdown (see [`TransitionalControlHandle::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 TransitionalRequestResponder {
    fn drop(&mut self) {
        self.control_handle.shutdown();
        // Safety: drops once, never accessed again
        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
    }
}

impl TransitionalRequestResponder {
    pub fn control_handle(&self) -> &TransitionalControlHandle {
        &self.control_handle
    }

    /// Drop the Responder without setting the channel to shutdown.
    ///
    /// This method shouldn't normally be used-- instead, send a response
    /// to prevent the channel from shutting down.
    pub 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);
    }

    /// Sends a response to the FIDL transaction.
    ///
    /// Sets the channel to shutdown if an error occurs.
    pub fn send(self, mut y: i64) -> Result<(), fidl::Error> {
        let r = self.send_raw(y);
        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 y: i64) -> Result<(), fidl::Error> {
        let r = self.send_raw(y);
        self.drop_without_shutdown();
        r
    }

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

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

        fidl::encoding::with_tls_encode_buf(|bytes, handles| {
            fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/TransitionalRequestResponse");
            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(())
        })
    }
}

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

impl fidl::endpoints::ServiceMarker for DiscoverableProtocolMarker {
    type Proxy = DiscoverableProtocolProxy;
    type RequestStream = DiscoverableProtocolRequestStream;
    const DEBUG_NAME: &'static str = "fidl.test.protocols.DiscoverableProtocol";
}
impl fidl::endpoints::DiscoverableService for DiscoverableProtocolMarker {}

pub trait DiscoverableProtocolProxyInterface: Send + Sync {
    fn r#method(&self) -> Result<(), fidl::Error>;
}

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

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

    pub fn into_channel(self) -> fidl::Channel {
        self.client.into_channel()
    }
    pub fn r#method(&mut self) -> Result<(), fidl::Error> {
        self.client.send(&mut (), 0x39790af74e0167)
    }
}

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

impl fidl::endpoints::Proxy for DiscoverableProtocolProxy {
    type Service = DiscoverableProtocolMarker;

    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 DiscoverableProtocolProxy {
    /// Create a new Proxy for DiscoverableProtocol
    pub fn new(channel: fidl::AsyncChannel) -> Self {
        let service_name =
            <DiscoverableProtocolMarker as fidl::endpoints::ServiceMarker>::DEBUG_NAME;
        Self { client: fidl::client::Client::new(channel, service_name) }
    }

    /// Get a Stream of events from the remote end of the DiscoverableProtocol protocol
    ///
    /// # Panics
    ///
    /// Panics if the event stream was already taken.
    pub fn take_event_stream(&self) -> DiscoverableProtocolEventStream {
        DiscoverableProtocolEventStream { event_receiver: self.client.take_event_receiver() }
    }
    pub fn r#method(&self) -> Result<(), fidl::Error> {
        DiscoverableProtocolProxyInterface::r#method(self)
    }
}

impl DiscoverableProtocolProxyInterface for DiscoverableProtocolProxy {
    fn r#method(&self) -> Result<(), fidl::Error> {
        self.client.send(&mut (), 0x39790af74e0167)
    }
}

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

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

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

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

    fn poll_next(
        mut self: std::pin::Pin<&mut Self>,
        cx: &mut std::task::Context<'_>,
    ) -> std::task::Poll<Option<Self::Item>> {
        let mut 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),
        };
        let (bytes, _handles) = buf.split_mut();
        let (tx_header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;

        std::task::Poll::Ready(Some(match tx_header.ordinal() {
            _ => Err(fidl::Error::UnknownOrdinal {
                ordinal: tx_header.ordinal(),
                service_name:
                    <DiscoverableProtocolMarker as fidl::endpoints::ServiceMarker>::DEBUG_NAME,
            }),
        }))
    }
}

#[derive(Debug)]
pub enum DiscoverableProtocolEvent {}

impl DiscoverableProtocolEvent {}

/// A type which can be used to send responses and events into a borrowed channel.
///
/// Note: this should only be used when the channel must be temporarily
/// borrowed. For a typical sending of events, use the send_ methods
/// on the ControlHandle types, which can be acquired through a
/// RequestStream or Responder type.
#[deprecated(note = "Use DiscoverableProtocolRequestStream / Responder instead")]
pub struct DiscoverableProtocolServerSender<'a> {
    // Some protocols don't define events which would render this channel unused.
    #[allow(dead_code)]
    channel: &'a fidl::Channel,
}

#[allow(deprecated)]
impl<'a> DiscoverableProtocolServerSender<'a> {
    pub fn new(channel: &'a fidl::Channel) -> Self {
        Self { channel }
    }
}

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

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

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

impl fidl::endpoints::RequestStream for DiscoverableProtocolRequestStream {
    type Service = DiscoverableProtocolMarker;

    /// Consume a channel to make a DiscoverableProtocolRequestStream
    fn from_channel(channel: fidl::AsyncChannel) -> Self {
        Self { inner: std::sync::Arc::new(fidl::ServeInner::new(channel)), is_terminated: false }
    }

    /// ControlHandle for the remote connection
    type ControlHandle = DiscoverableProtocolControlHandle;

    /// ControlHandle for the remote connection
    fn control_handle(&self) -> Self::ControlHandle {
        DiscoverableProtocolControlHandle { 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 DiscoverableProtocolRequestStream {
    type Item = Result<DiscoverableProtocolRequest, 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 DiscoverableProtocolRequestStream 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() {
                0x39790af74e0167 => {
                    let mut req: () = fidl::encoding::Decodable::new_empty();
                    fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/DiscoverableProtocolMethodRequest");
                    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 =
                        DiscoverableProtocolControlHandle { inner: this.inner.clone() };

                    Ok(DiscoverableProtocolRequest::Method { control_handle })
                }
                _ => Err(fidl::Error::UnknownOrdinal {
                    ordinal: header.ordinal(),
                    service_name:
                        <DiscoverableProtocolMarker as fidl::endpoints::ServiceMarker>::DEBUG_NAME,
                }),
            }))
        })
    }
}

/// Represents a single request.
/// RequestMessages should only be used for manual deserialization when higher level
/// structs such as RequestStream cannot be used. One usually would only encounter
/// such scenarios when working with legacy FIDL code (prior to FIDL generated client/server bindings).
#[derive(Debug)]
#[deprecated(note = "Use DiscoverableProtocolRequest instead")]
pub enum DiscoverableProtocolRequestMessage {
    Method {},
}

#[allow(deprecated)]
impl DiscoverableProtocolRequestMessage {
    pub fn decode(
        bytes: &[u8],
        _handles: &mut [fidl::HandleInfo],
    ) -> Result<DiscoverableProtocolRequestMessage, fidl::Error> {
        let (header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;

        match header.ordinal() {
            0x39790af74e0167 => {
                let mut out_tuple: () = fidl::encoding::Decodable::new_empty();
                fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/DiscoverableProtocolMethodRequest");
                fidl::trace_blob!("fidl:blob", "decode", bytes);
                fidl::encoding::Decoder::decode_into(
                    &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(DiscoverableProtocolRequestMessage::Method {})
            }
            _ => Err(fidl::Error::UnknownOrdinal {
                ordinal: header.ordinal(),
                service_name:
                    <DiscoverableProtocolMarker as fidl::endpoints::ServiceMarker>::DEBUG_NAME,
            }),
        }
    }
}
#[derive(Debug)]
pub enum DiscoverableProtocolRequest {
    Method { control_handle: DiscoverableProtocolControlHandle },
}

impl DiscoverableProtocolRequest {
    #[allow(irrefutable_let_patterns)]
    pub fn into_method(self) -> Option<(DiscoverableProtocolControlHandle)> {
        if let DiscoverableProtocolRequest::Method { control_handle } = self {
            Some((control_handle))
        } else {
            None
        }
    }

    /// Name of the method defined in FIDL
    pub fn method_name(&self) -> &'static str {
        match *self {
            DiscoverableProtocolRequest::Method { .. } => "method",
        }
    }
}

pub struct DiscoverableProtocolEncoder;

impl DiscoverableProtocolEncoder {
    pub fn encode_method_request<'a>(
        out_bytes: &'a mut Vec<u8>,
        out_handles: &'a mut Vec<fidl::HandleDisposition<'static>>,
    ) -> Result<(), fidl::Error> {
        let header = fidl::encoding::TransactionHeader::new(0, 0x39790af74e0167);
        let mut body = ();
        let mut msg = fidl::encoding::TransactionMessage { header, body: &mut body };
        fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.protocols/DiscoverableProtocolMethodRequest");
        fidl::encoding::Encoder::encode(out_bytes, out_handles, &mut msg)?;
        fidl::trace_blob!("fidl:blob", "encode", out_bytes.as_slice());
        fidl::duration_end!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "size" => out_bytes.len() as u32, "handle_count" => out_handles.len() as u32);
        Ok(())
    }
}

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

impl DiscoverableProtocolControlHandle {
    /// Set the server to shutdown. The underlying channel is only closed the
    /// next time the stream is polled.
    pub fn shutdown(&self) {
        self.inner.shutdown()
    }

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