// 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(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct Empty;

fidl_empty_struct!(Empty);

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

impl fidl::endpoints::ServiceMarker for EmptyProtocolMarker {
    type Proxy = EmptyProtocolProxy;
    type RequestStream = EmptyProtocolRequestStream;
    const DEBUG_NAME: &'static str = "(anonymous) EmptyProtocol";
}

pub trait EmptyProtocolProxyInterface: Send + Sync {
    fn r#send_(&self, e: &mut Empty) -> Result<(), fidl::Error>;
    type ReceiveResponseFut: std::future::Future<Output = Result<(Empty), fidl::Error>> + Send;
    type SendAndReceiveResponseFut: std::future::Future<Output = Result<(Empty), fidl::Error>>
        + Send;
    fn r#send_and_receive(&self, e: &mut Empty) -> Self::SendAndReceiveResponseFut;
}

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

#[cfg(target_os = "fuchsia")]
impl EmptyProtocolSynchronousProxy {
    pub fn new(channel: fidl::Channel) -> Self {
        let service_name = <EmptyProtocolMarker 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#send_(&mut self, mut e: &mut Empty) -> Result<(), fidl::Error> {
        self.client.send(&mut (e), 0x1e4e78d0556b6f28)
    }
    pub fn r#send_and_receive(
        &mut self,
        mut e: &mut Empty,
        ___deadline: zx::Time,
    ) -> Result<(Empty), fidl::Error> {
        let _value: (Empty,) = self.client.send_query(&mut (e), 0x56ca6bd78bac3571, ___deadline)?;
        Ok(_value.0)
    }
}

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

impl fidl::endpoints::Proxy for EmptyProtocolProxy {
    type Service = EmptyProtocolMarker;

    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 EmptyProtocolProxy {
    /// Create a new Proxy for EmptyProtocol
    pub fn new(channel: fidl::AsyncChannel) -> Self {
        let service_name = <EmptyProtocolMarker 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 EmptyProtocol protocol
    ///
    /// # Panics
    ///
    /// Panics if the event stream was already taken.
    pub fn take_event_stream(&self) -> EmptyProtocolEventStream {
        EmptyProtocolEventStream { event_receiver: self.client.take_event_receiver() }
    }
    pub fn r#send_(&self, mut e: &mut Empty) -> Result<(), fidl::Error> {
        EmptyProtocolProxyInterface::r#send_(self, e)
    }
    pub fn r#send_and_receive(&self, mut e: &mut Empty) -> fidl::client::QueryResponseFut<(Empty)> {
        EmptyProtocolProxyInterface::r#send_and_receive(self, e)
    }
}

impl EmptyProtocolProxyInterface for EmptyProtocolProxy {
    fn r#send_(&self, mut e: &mut Empty) -> Result<(), fidl::Error> {
        self.client.send(&mut (e), 0x1e4e78d0556b6f28)
    }
    type ReceiveResponseFut = fidl::client::QueryResponseFut<(Empty)>;
    type SendAndReceiveResponseFut = fidl::client::QueryResponseFut<(Empty)>;
    fn r#send_and_receive(&self, mut e: &mut Empty) -> Self::SendAndReceiveResponseFut {
        fn transform(result: Result<(Empty,), fidl::Error>) -> Result<(Empty), fidl::Error> {
            result.map(|_value| _value.0)
        }
        let send_result = self.client.call_send_raw_query(&mut (e), 0x56ca6bd78bac3571);
        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 EmptyProtocolEventStream {
    event_receiver: fidl::client::EventReceiver,
}

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

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

impl futures::Stream for EmptyProtocolEventStream {
    type Item = Result<EmptyProtocolEvent, 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() {
            0x45bd261c537791e0 => {
                let mut out_tuple: (Empty,) = fidl::encoding::Decodable::new_empty();
                fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.emptystruct/EmptyProtocolReceiveEvent");
                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((EmptyProtocolEvent::Receive { e: out_tuple.0 }))
            }
            _ => Err(fidl::Error::UnknownOrdinal {
                ordinal: tx_header.ordinal(),
                service_name: <EmptyProtocolMarker as fidl::endpoints::ServiceMarker>::DEBUG_NAME,
            }),
        }))
    }
}

#[derive(Debug)]
pub enum EmptyProtocolEvent {
    Receive { e: Empty },
}

impl EmptyProtocolEvent {
    #[allow(irrefutable_let_patterns)]
    pub fn into_receive(self) -> Option<(Empty)> {
        if let EmptyProtocolEvent::Receive { e } = self {
            Some((e))
        } 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 EmptyProtocolRequestStream / Responder instead")]
pub struct EmptyProtocolServerSender<'a> {
    // Some protocols don't define events which would render this channel unused.
    #[allow(dead_code)]
    channel: &'a fidl::Channel,
}

#[allow(deprecated)]
impl<'a> EmptyProtocolServerSender<'a> {
    pub fn new(channel: &'a fidl::Channel) -> Self {
        Self { channel }
    }
    pub fn send_receive(&self, mut e: &mut Empty) -> Result<(), fidl::Error> {
        fidl::encoding::with_tls_encode_buf(|bytes_, handles_| {
            EmptyProtocolEncoder::encode_receive_response(bytes_, handles_, e)?;
            self.channel
                .write_etc(&*bytes_, &mut *handles_)
                .map_err(fidl::Error::ServerResponseWrite)?;
            Ok(())
        })
    }
    pub fn send_send_and_receive_response(
        &self,
        txid: fidl::client::Txid,
        mut e: &mut Empty,
    ) -> Result<(), fidl::Error> {
        fidl::encoding::with_tls_encode_buf(|bytes_, handles_| {
            EmptyProtocolEncoder::encode_send_and_receive_response(
                bytes_,
                handles_,
                txid.as_raw_id(),
                e,
            )?;
            self.channel
                .write_etc(&*bytes_, &mut *handles_)
                .map_err(fidl::Error::ServerResponseWrite)?;
            Ok(())
        })
    }
}

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

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

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

impl fidl::endpoints::RequestStream for EmptyProtocolRequestStream {
    type Service = EmptyProtocolMarker;

    /// Consume a channel to make a EmptyProtocolRequestStream
    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 = EmptyProtocolControlHandle;

    /// ControlHandle for the remote connection
    fn control_handle(&self) -> Self::ControlHandle {
        EmptyProtocolControlHandle { 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 EmptyProtocolRequestStream {
    type Item = Result<EmptyProtocolRequest, 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 EmptyProtocolRequestStream 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() {
                0x1e4e78d0556b6f28 => {
                    let mut req: (Empty,) = fidl::encoding::Decodable::new_empty();
                    fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.emptystruct/EmptyProtocolSend_Request");
                    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 = EmptyProtocolControlHandle { inner: this.inner.clone() };

                    Ok(EmptyProtocolRequest::Send_ { e: req.0, control_handle })
                }
                0x56ca6bd78bac3571 => {
                    let mut req: (Empty,) = fidl::encoding::Decodable::new_empty();
                    fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.emptystruct/EmptyProtocolSendAndReceiveRequest");
                    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 = EmptyProtocolControlHandle { inner: this.inner.clone() };

                    Ok(EmptyProtocolRequest::SendAndReceive {
                        e: req.0,
                        responder: EmptyProtocolSendAndReceiveResponder {
                            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:
                        <EmptyProtocolMarker 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 EmptyProtocolRequest instead")]
pub enum EmptyProtocolRequestMessage {
    Send_ { e: Empty },
    SendAndReceive { e: Empty, tx_id: fidl::client::Txid },
}

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

        match header.ordinal() {
            0x1e4e78d0556b6f28 => {
                let mut out_tuple: (Empty,) = fidl::encoding::Decodable::new_empty();
                fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.emptystruct/EmptyProtocolSend_Request");
                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(EmptyProtocolRequestMessage::Send_ { e: out_tuple.0 })
            }
            0x56ca6bd78bac3571 => {
                let mut out_tuple: (Empty,) = fidl::encoding::Decodable::new_empty();
                fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.emptystruct/EmptyProtocolSendAndReceiveRequest");
                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(EmptyProtocolRequestMessage::SendAndReceive {
                    e: out_tuple.0,
                    tx_id: header.tx_id().into(),
                })
            }
            _ => Err(fidl::Error::UnknownOrdinal {
                ordinal: header.ordinal(),
                service_name: <EmptyProtocolMarker as fidl::endpoints::ServiceMarker>::DEBUG_NAME,
            }),
        }
    }
}
#[derive(Debug)]
pub enum EmptyProtocolRequest {
    Send_ { e: Empty, control_handle: EmptyProtocolControlHandle },
    SendAndReceive { e: Empty, responder: EmptyProtocolSendAndReceiveResponder },
}

impl EmptyProtocolRequest {
    #[allow(irrefutable_let_patterns)]
    pub fn into_send_(self) -> Option<(Empty, EmptyProtocolControlHandle)> {
        if let EmptyProtocolRequest::Send_ { e, control_handle } = self {
            Some((e, control_handle))
        } else {
            None
        }
    }

    #[allow(irrefutable_let_patterns)]
    pub fn into_send_and_receive(self) -> Option<(Empty, EmptyProtocolSendAndReceiveResponder)> {
        if let EmptyProtocolRequest::SendAndReceive { e, responder } = self {
            Some((e, responder))
        } else {
            None
        }
    }

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

pub struct EmptyProtocolEncoder;

impl EmptyProtocolEncoder {
    pub fn encode_send__request<'a>(
        out_bytes: &'a mut Vec<u8>,
        out_handles: &'a mut Vec<fidl::HandleDisposition<'static>>,
        mut in_e: &mut Empty,
    ) -> Result<(), fidl::Error> {
        let header = fidl::encoding::TransactionHeader::new(0, 0x1e4e78d0556b6f28);
        let mut body = (in_e,);
        let mut msg = fidl::encoding::TransactionMessage { header, body: &mut body };
        fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.emptystruct/EmptyProtocolSend_Request");
        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_receive_response<'a>(
        out_bytes: &'a mut Vec<u8>,
        out_handles: &'a mut Vec<fidl::HandleDisposition<'static>>,
        mut in_e: &mut Empty,
    ) -> Result<(), fidl::Error> {
        let header = fidl::encoding::TransactionHeader::new(0, 0x45bd261c537791e0);
        let mut body = (in_e,);
        let mut msg = fidl::encoding::TransactionMessage { header, body: &mut body };

        fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.emptystruct/EmptyProtocolReceiveResponse");
        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_send_and_receive_request<'a>(
        out_bytes: &'a mut Vec<u8>,
        out_handles: &'a mut Vec<fidl::HandleDisposition<'static>>,
        tx_id: u32,
        mut in_e: &mut Empty,
    ) -> Result<(), fidl::Error> {
        let header = fidl::encoding::TransactionHeader::new(tx_id, 0x56ca6bd78bac3571);
        let mut body = (in_e,);
        let mut msg = fidl::encoding::TransactionMessage { header, body: &mut body };
        fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.emptystruct/EmptyProtocolSendAndReceiveRequest");
        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_send_and_receive_response<'a>(
        out_bytes: &'a mut Vec<u8>,
        out_handles: &'a mut Vec<fidl::HandleDisposition<'static>>,
        tx_id: u32,
        mut in_e: &mut Empty,
    ) -> Result<(), fidl::Error> {
        let header = fidl::encoding::TransactionHeader::new(tx_id, 0x56ca6bd78bac3571);
        let mut body = (in_e,);
        let mut msg = fidl::encoding::TransactionMessage { header, body: &mut body };

        fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.emptystruct/EmptyProtocolSendAndReceiveResponse");
        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 EmptyProtocolControlHandle {
    inner: std::sync::Arc<fidl::ServeInner>,
}

impl EmptyProtocolControlHandle {
    /// 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_receive(&self, mut e: &mut Empty) -> Result<(), fidl::Error> {
        let mut response = (e);

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

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

impl EmptyProtocolSendAndReceiveResponder {
    pub fn control_handle(&self) -> &EmptyProtocolControlHandle {
        &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 e: &mut Empty) -> Result<(), fidl::Error> {
        let r = self.send_raw(e);
        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 e: &mut Empty) -> Result<(), fidl::Error> {
        let r = self.send_raw(e);
        self.drop_without_shutdown();
        r
    }

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

        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.emptystruct/EmptyProtocolSendAndReceiveResponse");
            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(())
        })
    }
}
