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

// fidl_experiment = output_index_json

#![warn(clippy::all)]
#![allow(unused_parens, unused_mut, unused_imports, nonstandard_style)]

use bitflags::bitflags;
use fidl::client::QueryResponseFut;
use fidl::encoding::{MessageBufFor, ProxyChannelBox, ResourceDialect};
use fidl::endpoints::{ControlHandle as _, Responder as _};
pub use fidl_test_emptystruct__common::*;
use futures::future::{self, MaybeDone, TryFutureExt};
use zx_status;

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

impl fidl::endpoints::ProtocolMarker for EmptyProtocolMarker {
    type Proxy = EmptyProtocolProxy;
    type RequestStream = EmptyProtocolRequestStream;
    #[cfg(target_os = "fuchsia")]
    type SynchronousProxy = EmptyProtocolSynchronousProxy;

    const DEBUG_NAME: &'static str = "(anonymous) EmptyProtocol";
}

pub trait EmptyProtocolProxyInterface: Send + Sync {
    fn r#send_(&self, e: &Empty) -> Result<(), fidl::Error>;
    type SendAndReceiveResponseFut: std::future::Future<Output = Result<Empty, fidl::Error>> + Send;
    fn r#send_and_receive(&self, e: &Empty) -> Self::SendAndReceiveResponseFut;
}
#[derive(Debug)]
#[cfg(target_os = "fuchsia")]
pub struct EmptyProtocolSynchronousProxy {
    client: fidl::client::sync::Client,
}

#[cfg(target_os = "fuchsia")]
impl fidl::endpoints::SynchronousProxy for EmptyProtocolSynchronousProxy {
    type Proxy = EmptyProtocolProxy;
    type Protocol = EmptyProtocolMarker;

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

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

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

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

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

    /// Waits until an event arrives and returns it. It is safe for other
    /// threads to make concurrent requests while waiting for an event.
    pub fn wait_for_event(
        &self,
        deadline: zx::MonotonicInstant,
    ) -> Result<EmptyProtocolEvent, fidl::Error> {
        EmptyProtocolEvent::decode(self.client.wait_for_event(deadline)?)
    }

    pub fn r#send_(&self, mut e: &Empty) -> Result<(), fidl::Error> {
        self.client.send::<EmptyProtocolSendRequest>(
            (e,),
            0x132262fd8b200708,
            fidl::encoding::DynamicFlags::empty(),
        )
    }

    pub fn r#send_and_receive(
        &self,
        mut e: &Empty,
        ___deadline: zx::MonotonicInstant,
    ) -> Result<Empty, fidl::Error> {
        let _response = self
            .client
            .send_query::<EmptyProtocolSendAndReceiveRequest, EmptyProtocolSendAndReceiveResponse>(
                (e,),
                0x76a931254962cea,
                fidl::encoding::DynamicFlags::empty(),
                ___deadline,
            )?;
        Ok(_response.e)
    }
}

#[cfg(target_os = "fuchsia")]
impl From<EmptyProtocolSynchronousProxy> for zx::Handle {
    fn from(value: EmptyProtocolSynchronousProxy) -> Self {
        value.into_channel().into()
    }
}

#[cfg(target_os = "fuchsia")]
impl From<fidl::Channel> for EmptyProtocolSynchronousProxy {
    fn from(value: fidl::Channel) -> Self {
        Self::new(value)
    }
}

#[cfg(target_os = "fuchsia")]
impl fidl::endpoints::FromClient for EmptyProtocolSynchronousProxy {
    type Protocol = EmptyProtocolMarker;

    fn from_client(value: fidl::endpoints::ClientEnd<EmptyProtocolMarker>) -> Self {
        Self::new(value.into_channel())
    }
}

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

impl fidl::endpoints::Proxy for EmptyProtocolProxy {
    type Protocol = 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 test.emptystruct/EmptyProtocol.
    pub fn new(channel: ::fidl::AsyncChannel) -> Self {
        let protocol_name = <EmptyProtocolMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
        Self { client: fidl::client::Client::new(channel, protocol_name) }
    }

    /// Get a Stream of events from the remote end of the 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: &Empty) -> Result<(), fidl::Error> {
        EmptyProtocolProxyInterface::r#send_(self, e)
    }

    pub fn r#send_and_receive(
        &self,
        mut e: &Empty,
    ) -> fidl::client::QueryResponseFut<Empty, fidl::encoding::DefaultFuchsiaResourceDialect> {
        EmptyProtocolProxyInterface::r#send_and_receive(self, e)
    }
}

impl EmptyProtocolProxyInterface for EmptyProtocolProxy {
    fn r#send_(&self, mut e: &Empty) -> Result<(), fidl::Error> {
        self.client.send::<EmptyProtocolSendRequest>(
            (e,),
            0x132262fd8b200708,
            fidl::encoding::DynamicFlags::empty(),
        )
    }

    type SendAndReceiveResponseFut =
        fidl::client::QueryResponseFut<Empty, fidl::encoding::DefaultFuchsiaResourceDialect>;
    fn r#send_and_receive(&self, mut e: &Empty) -> Self::SendAndReceiveResponseFut {
        fn _decode(
            mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
        ) -> Result<Empty, fidl::Error> {
            let _response = fidl::client::decode_transaction_body::<
                EmptyProtocolSendAndReceiveResponse,
                fidl::encoding::DefaultFuchsiaResourceDialect,
                0x76a931254962cea,
            >(_buf?)?;
            Ok(_response.e)
        }
        self.client.send_query_and_decode::<EmptyProtocolSendAndReceiveRequest, Empty>(
            (e,),
            0x76a931254962cea,
            fidl::encoding::DynamicFlags::empty(),
            _decode,
        )
    }
}

pub struct EmptyProtocolEventStream {
    event_receiver: fidl::client::EventReceiver<fidl::encoding::DefaultFuchsiaResourceDialect>,
}

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>> {
        match futures::ready!(futures::stream::StreamExt::poll_next_unpin(
            &mut self.event_receiver,
            cx
        )?) {
            Some(buf) => std::task::Poll::Ready(Some(EmptyProtocolEvent::decode(buf))),
            None => std::task::Poll::Ready(None),
        }
    }
}

#[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 }
    }

    /// Decodes a message buffer as a [`EmptyProtocolEvent`].
    fn decode(
        mut buf: <fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc,
    ) -> Result<EmptyProtocolEvent, fidl::Error> {
        let (bytes, _handles) = buf.split_mut();
        let (tx_header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
        debug_assert_eq!(tx_header.tx_id, 0);
        match tx_header.ordinal {
            0x1ff0ccf9b710e23f => {
                let mut out = fidl::new_empty!(
                    EmptyProtocolReceiveRequest,
                    fidl::encoding::DefaultFuchsiaResourceDialect
                );
                fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<EmptyProtocolReceiveRequest>(&tx_header, _body_bytes, _handles, &mut out)?;
                Ok((EmptyProtocolEvent::Receive { e: out.e }))
            }
            _ => Err(fidl::Error::UnknownOrdinal {
                ordinal: tx_header.ordinal,
                protocol_name: <EmptyProtocolMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
            }),
        }
    }
}

/// A Stream of incoming requests for test.emptystruct/EmptyProtocol.
pub struct EmptyProtocolRequestStream {
    inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
    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 Protocol = EmptyProtocolMarker;
    type ControlHandle = EmptyProtocolControlHandle;

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

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

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

    fn from_inner(
        inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
        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.check_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::<_, fidl::encoding::DefaultFuchsiaResourceDialect>(
            |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.into(),
                        ))));
                    }
                }

                // A message has been received from the channel
                let (header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;

                std::task::Poll::Ready(Some(match header.ordinal {
                    0x132262fd8b200708 => {
                        header.validate_request_tx_id(fidl::MethodType::OneWay)?;
                        let mut req = fidl::new_empty!(
                            EmptyProtocolSendRequest,
                            fidl::encoding::DefaultFuchsiaResourceDialect
                        );
                        fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<EmptyProtocolSendRequest>(&header, _body_bytes, handles, &mut req)?;
                        let control_handle =
                            EmptyProtocolControlHandle { inner: this.inner.clone() };
                        Ok(EmptyProtocolRequest::Send_ { e: req.e, control_handle })
                    }
                    0x76a931254962cea => {
                        header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
                        let mut req = fidl::new_empty!(
                            EmptyProtocolSendAndReceiveRequest,
                            fidl::encoding::DefaultFuchsiaResourceDialect
                        );
                        fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<EmptyProtocolSendAndReceiveRequest>(&header, _body_bytes, handles, &mut req)?;
                        let control_handle =
                            EmptyProtocolControlHandle { inner: this.inner.clone() };
                        Ok(EmptyProtocolRequest::SendAndReceive {
                            e: req.e,

                            responder: EmptyProtocolSendAndReceiveResponder {
                                control_handle: std::mem::ManuallyDrop::new(control_handle),
                                tx_id: header.tx_id,
                            },
                        })
                    }
                    _ => Err(fidl::Error::UnknownOrdinal {
                        ordinal: header.ordinal,
                        protocol_name:
                            <EmptyProtocolMarker as fidl::endpoints::ProtocolMarker>::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",
        }
    }
}

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

impl fidl::endpoints::ControlHandle for EmptyProtocolControlHandle {
    fn shutdown(&self) {
        self.inner.shutdown()
    }
    fn shutdown_with_epitaph(&self, status: zx_status::Status) {
        self.inner.shutdown_with_epitaph(status)
    }

    fn is_closed(&self) -> bool {
        self.inner.channel().is_closed()
    }
    fn on_closed(&self) -> fidl::OnSignalsRef<'_> {
        self.inner.channel().on_closed()
    }

    #[cfg(target_os = "fuchsia")]
    fn signal_peer(
        &self,
        clear_mask: zx::Signals,
        set_mask: zx::Signals,
    ) -> Result<(), zx_status::Status> {
        use fidl::Peered;
        self.inner.channel().signal_peer(clear_mask, set_mask)
    }
}

impl EmptyProtocolControlHandle {
    pub fn send_receive(&self, mut e: &Empty) -> Result<(), fidl::Error> {
        self.inner.send::<EmptyProtocolReceiveRequest>(
            (e,),
            0,
            0x1ff0ccf9b710e23f,
            fidl::encoding::DynamicFlags::empty(),
        )
    }
}

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

/// 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 fidl::endpoints::Responder for EmptyProtocolSendAndReceiveResponder {
    type ControlHandle = EmptyProtocolControlHandle;

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

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

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

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

    fn send_raw(&self, mut e: &Empty) -> Result<(), fidl::Error> {
        self.control_handle.inner.send::<EmptyProtocolSendAndReceiveResponse>(
            (e,),
            self.tx_id,
            0x76a931254962cea,
            fidl::encoding::DynamicFlags::empty(),
        )
    }
}

mod internal {
    use super::*;
}
