// 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 FirstProtocolMarker;

impl fidl::endpoints::ServiceMarker for FirstProtocolMarker {
    type Proxy = FirstProtocolProxy;
    type RequestStream = FirstProtocolRequestStream;
    const DEBUG_NAME: &'static str = "(anonymous) FirstProtocol";
}

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

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

#[cfg(target_os = "fuchsia")]
impl FirstProtocolSynchronousProxy {
    pub fn new(channel: fidl::Channel) -> Self {
        let service_name = <FirstProtocolMarker 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_on_first(&mut self) -> Result<(), fidl::Error> {
        self.client.send(&mut (), 0x5b76bb4db7c2bba4)
    }
}

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

impl fidl::endpoints::Proxy for FirstProtocolProxy {
    type Service = FirstProtocolMarker;

    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 FirstProtocolProxy {
    /// Create a new Proxy for FirstProtocol
    pub fn new(channel: fidl::AsyncChannel) -> Self {
        let service_name = <FirstProtocolMarker 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 FirstProtocol protocol
    ///
    /// # Panics
    ///
    /// Panics if the event stream was already taken.
    pub fn take_event_stream(&self) -> FirstProtocolEventStream {
        FirstProtocolEventStream { event_receiver: self.client.take_event_receiver() }
    }
    pub fn r#method_on_first(&self) -> Result<(), fidl::Error> {
        FirstProtocolProxyInterface::r#method_on_first(self)
    }
}

impl FirstProtocolProxyInterface for FirstProtocolProxy {
    fn r#method_on_first(&self) -> Result<(), fidl::Error> {
        self.client.send(&mut (), 0x5b76bb4db7c2bba4)
    }
}

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

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

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

impl futures::Stream for FirstProtocolEventStream {
    type Item = Result<FirstProtocolEvent, 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: <FirstProtocolMarker as fidl::endpoints::ServiceMarker>::DEBUG_NAME,
            }),
        }))
    }
}

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

impl FirstProtocolEvent {}

/// 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 FirstProtocolRequestStream / Responder instead")]
pub struct FirstProtocolServerSender<'a> {
    // Some protocols don't define events which would render this channel unused.
    #[allow(dead_code)]
    channel: &'a fidl::Channel,
}

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

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

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

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

impl fidl::endpoints::RequestStream for FirstProtocolRequestStream {
    type Service = FirstProtocolMarker;

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

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

                    Ok(FirstProtocolRequest::MethodOnFirst { control_handle })
                }
                _ => Err(fidl::Error::UnknownOrdinal {
                    ordinal: header.ordinal(),
                    service_name:
                        <FirstProtocolMarker 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 FirstProtocolRequest instead")]
pub enum FirstProtocolRequestMessage {
    MethodOnFirst {},
}

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

        match header.ordinal() {
            0x5b76bb4db7c2bba4 => {
                let mut out_tuple: () = fidl::encoding::Decodable::new_empty();
                fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.service/FirstProtocolMethodOnFirstRequest");
                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(FirstProtocolRequestMessage::MethodOnFirst {})
            }
            _ => Err(fidl::Error::UnknownOrdinal {
                ordinal: header.ordinal(),
                service_name: <FirstProtocolMarker as fidl::endpoints::ServiceMarker>::DEBUG_NAME,
            }),
        }
    }
}
#[derive(Debug)]
pub enum FirstProtocolRequest {
    MethodOnFirst { control_handle: FirstProtocolControlHandle },
}

impl FirstProtocolRequest {
    #[allow(irrefutable_let_patterns)]
    pub fn into_method_on_first(self) -> Option<(FirstProtocolControlHandle)> {
        if let FirstProtocolRequest::MethodOnFirst { control_handle } = self {
            Some((control_handle))
        } else {
            None
        }
    }

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

pub struct FirstProtocolEncoder;

impl FirstProtocolEncoder {
    pub fn encode_method_on_first_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, 0x5b76bb4db7c2bba4);
        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.service/FirstProtocolMethodOnFirstRequest");
        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 FirstProtocolControlHandle {
    inner: std::sync::Arc<fidl::ServeInner>,
}

impl FirstProtocolControlHandle {
    /// 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)
    }
}

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

impl fidl::endpoints::ServiceMarker for SecondProtocolMarker {
    type Proxy = SecondProtocolProxy;
    type RequestStream = SecondProtocolRequestStream;
    const DEBUG_NAME: &'static str = "(anonymous) SecondProtocol";
}

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

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

#[cfg(target_os = "fuchsia")]
impl SecondProtocolSynchronousProxy {
    pub fn new(channel: fidl::Channel) -> Self {
        let service_name = <SecondProtocolMarker 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_on_second(&mut self) -> Result<(), fidl::Error> {
        self.client.send(&mut (), 0x54ea6448c1555a29)
    }
}

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

impl fidl::endpoints::Proxy for SecondProtocolProxy {
    type Service = SecondProtocolMarker;

    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 SecondProtocolProxy {
    /// Create a new Proxy for SecondProtocol
    pub fn new(channel: fidl::AsyncChannel) -> Self {
        let service_name = <SecondProtocolMarker 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 SecondProtocol protocol
    ///
    /// # Panics
    ///
    /// Panics if the event stream was already taken.
    pub fn take_event_stream(&self) -> SecondProtocolEventStream {
        SecondProtocolEventStream { event_receiver: self.client.take_event_receiver() }
    }
    pub fn r#method_on_second(&self) -> Result<(), fidl::Error> {
        SecondProtocolProxyInterface::r#method_on_second(self)
    }
}

impl SecondProtocolProxyInterface for SecondProtocolProxy {
    fn r#method_on_second(&self) -> Result<(), fidl::Error> {
        self.client.send(&mut (), 0x54ea6448c1555a29)
    }
}

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

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

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

impl futures::Stream for SecondProtocolEventStream {
    type Item = Result<SecondProtocolEvent, 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: <SecondProtocolMarker as fidl::endpoints::ServiceMarker>::DEBUG_NAME,
            }),
        }))
    }
}

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

impl SecondProtocolEvent {}

/// 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 SecondProtocolRequestStream / Responder instead")]
pub struct SecondProtocolServerSender<'a> {
    // Some protocols don't define events which would render this channel unused.
    #[allow(dead_code)]
    channel: &'a fidl::Channel,
}

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

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

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

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

impl fidl::endpoints::RequestStream for SecondProtocolRequestStream {
    type Service = SecondProtocolMarker;

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

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

                    Ok(SecondProtocolRequest::MethodOnSecond { control_handle })
                }
                _ => Err(fidl::Error::UnknownOrdinal {
                    ordinal: header.ordinal(),
                    service_name:
                        <SecondProtocolMarker 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 SecondProtocolRequest instead")]
pub enum SecondProtocolRequestMessage {
    MethodOnSecond {},
}

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

        match header.ordinal() {
            0x54ea6448c1555a29 => {
                let mut out_tuple: () = fidl::encoding::Decodable::new_empty();
                fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.service/SecondProtocolMethodOnSecondRequest");
                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(SecondProtocolRequestMessage::MethodOnSecond {})
            }
            _ => Err(fidl::Error::UnknownOrdinal {
                ordinal: header.ordinal(),
                service_name: <SecondProtocolMarker as fidl::endpoints::ServiceMarker>::DEBUG_NAME,
            }),
        }
    }
}
#[derive(Debug)]
pub enum SecondProtocolRequest {
    MethodOnSecond { control_handle: SecondProtocolControlHandle },
}

impl SecondProtocolRequest {
    #[allow(irrefutable_let_patterns)]
    pub fn into_method_on_second(self) -> Option<(SecondProtocolControlHandle)> {
        if let SecondProtocolRequest::MethodOnSecond { control_handle } = self {
            Some((control_handle))
        } else {
            None
        }
    }

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

pub struct SecondProtocolEncoder;

impl SecondProtocolEncoder {
    pub fn encode_method_on_second_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, 0x54ea6448c1555a29);
        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.service/SecondProtocolMethodOnSecondRequest");
        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 SecondProtocolControlHandle {
    inner: std::sync::Arc<fidl::ServeInner>,
}

impl SecondProtocolControlHandle {
    /// 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)
    }
}

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

#[cfg(target_os = "fuchsia")]
impl fidl::endpoints::UnifiedServiceMarker for EmptyServiceMarker {
    type Proxy = EmptyServiceProxy;
    type Request = EmptyServiceRequest;
    const SERVICE_NAME: &'static str = "fidl.test.service.EmptyService";
}

/// A request for one of the member protocols of EmptyService.
///
#[cfg(target_os = "fuchsia")]
pub enum EmptyServiceRequest {}

#[cfg(target_os = "fuchsia")]
impl fidl::endpoints::UnifiedServiceRequest for EmptyServiceRequest {
    type Service = EmptyServiceMarker;

    fn dispatch(name: &str, _channel: fidl::AsyncChannel) -> Self {
        match name {
            _ => panic!("no such member protocol name for service EmptyService"),
        }
    }

    fn member_names() -> &'static [&'static str] {
        &[]
    }
}
#[cfg(target_os = "fuchsia")]
pub struct EmptyServiceProxy(Box<dyn fidl::endpoints::MemberOpener>);

#[cfg(target_os = "fuchsia")]
impl fidl::endpoints::UnifiedServiceProxy for EmptyServiceProxy {
    type Service = EmptyServiceMarker;

    fn from_member_opener(opener: Box<dyn fidl::endpoints::MemberOpener>) -> Self {
        Self(opener)
    }
}

#[cfg(target_os = "fuchsia")]
impl EmptyServiceProxy {}

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

#[cfg(target_os = "fuchsia")]
impl fidl::endpoints::UnifiedServiceMarker for SingleMemberServiceMarker {
    type Proxy = SingleMemberServiceProxy;
    type Request = SingleMemberServiceRequest;
    const SERVICE_NAME: &'static str = "fidl.test.service.SingleMemberService";
}

/// A request for one of the member protocols of SingleMemberService.
///
#[cfg(target_os = "fuchsia")]
pub enum SingleMemberServiceRequest {
    SingleMember(FirstProtocolRequestStream),
}

#[cfg(target_os = "fuchsia")]
impl fidl::endpoints::UnifiedServiceRequest for SingleMemberServiceRequest {
    type Service = SingleMemberServiceMarker;

    fn dispatch(name: &str, _channel: fidl::AsyncChannel) -> Self {
        match name {
            "single_member" => Self::SingleMember(
                <FirstProtocolRequestStream as fidl::endpoints::RequestStream>::from_channel(
                    _channel,
                ),
            ),
            _ => panic!("no such member protocol name for service SingleMemberService"),
        }
    }

    fn member_names() -> &'static [&'static str] {
        &["single_member"]
    }
}
#[cfg(target_os = "fuchsia")]
pub struct SingleMemberServiceProxy(Box<dyn fidl::endpoints::MemberOpener>);

#[cfg(target_os = "fuchsia")]
impl fidl::endpoints::UnifiedServiceProxy for SingleMemberServiceProxy {
    type Service = SingleMemberServiceMarker;

    fn from_member_opener(opener: Box<dyn fidl::endpoints::MemberOpener>) -> Self {
        Self(opener)
    }
}

#[cfg(target_os = "fuchsia")]
impl SingleMemberServiceProxy {
    pub fn single_member(&self) -> Result<FirstProtocolProxy, fidl::Error> {
        let (proxy, server) = zx::Channel::create().map_err(fidl::Error::ChannelPairCreate)?;
        self.0.open_member("single_member", server)?;
        let proxy = fidl::AsyncChannel::from_channel(proxy).map_err(fidl::Error::AsyncChannel)?;
        Ok(FirstProtocolProxy::new(proxy))
    }
}

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

#[cfg(target_os = "fuchsia")]
impl fidl::endpoints::UnifiedServiceMarker for MultiHeterogeneousMemberServiceMarker {
    type Proxy = MultiHeterogeneousMemberServiceProxy;
    type Request = MultiHeterogeneousMemberServiceRequest;
    const SERVICE_NAME: &'static str = "fidl.test.service.MultiHeterogeneousMemberService";
}

/// A request for one of the member protocols of MultiHeterogeneousMemberService.
///
#[cfg(target_os = "fuchsia")]
pub enum MultiHeterogeneousMemberServiceRequest {
    FirstMember(FirstProtocolRequestStream),
    SecondMember(SecondProtocolRequestStream),
}

#[cfg(target_os = "fuchsia")]
impl fidl::endpoints::UnifiedServiceRequest for MultiHeterogeneousMemberServiceRequest {
    type Service = MultiHeterogeneousMemberServiceMarker;

    fn dispatch(name: &str, _channel: fidl::AsyncChannel) -> Self {
        match name {
            "first_member" => Self::FirstMember(
                <FirstProtocolRequestStream as fidl::endpoints::RequestStream>::from_channel(
                    _channel,
                ),
            ),
            "second_member" => Self::SecondMember(
                <SecondProtocolRequestStream as fidl::endpoints::RequestStream>::from_channel(
                    _channel,
                ),
            ),
            _ => panic!("no such member protocol name for service MultiHeterogeneousMemberService"),
        }
    }

    fn member_names() -> &'static [&'static str] {
        &["first_member", "second_member"]
    }
}
#[cfg(target_os = "fuchsia")]
pub struct MultiHeterogeneousMemberServiceProxy(Box<dyn fidl::endpoints::MemberOpener>);

#[cfg(target_os = "fuchsia")]
impl fidl::endpoints::UnifiedServiceProxy for MultiHeterogeneousMemberServiceProxy {
    type Service = MultiHeterogeneousMemberServiceMarker;

    fn from_member_opener(opener: Box<dyn fidl::endpoints::MemberOpener>) -> Self {
        Self(opener)
    }
}

#[cfg(target_os = "fuchsia")]
impl MultiHeterogeneousMemberServiceProxy {
    pub fn first_member(&self) -> Result<FirstProtocolProxy, fidl::Error> {
        let (proxy, server) = zx::Channel::create().map_err(fidl::Error::ChannelPairCreate)?;
        self.0.open_member("first_member", server)?;
        let proxy = fidl::AsyncChannel::from_channel(proxy).map_err(fidl::Error::AsyncChannel)?;
        Ok(FirstProtocolProxy::new(proxy))
    }
    pub fn second_member(&self) -> Result<SecondProtocolProxy, fidl::Error> {
        let (proxy, server) = zx::Channel::create().map_err(fidl::Error::ChannelPairCreate)?;
        self.0.open_member("second_member", server)?;
        let proxy = fidl::AsyncChannel::from_channel(proxy).map_err(fidl::Error::AsyncChannel)?;
        Ok(SecondProtocolProxy::new(proxy))
    }
}

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

#[cfg(target_os = "fuchsia")]
impl fidl::endpoints::UnifiedServiceMarker for MultiHomogeneousMemberServiceMarker {
    type Proxy = MultiHomogeneousMemberServiceProxy;
    type Request = MultiHomogeneousMemberServiceRequest;
    const SERVICE_NAME: &'static str = "fidl.test.service.MultiHomogeneousMemberService";
}

/// A request for one of the member protocols of MultiHomogeneousMemberService.
///
#[cfg(target_os = "fuchsia")]
pub enum MultiHomogeneousMemberServiceRequest {
    FirstMember(FirstProtocolRequestStream),
    SecondMember(FirstProtocolRequestStream),
}

#[cfg(target_os = "fuchsia")]
impl fidl::endpoints::UnifiedServiceRequest for MultiHomogeneousMemberServiceRequest {
    type Service = MultiHomogeneousMemberServiceMarker;

    fn dispatch(name: &str, _channel: fidl::AsyncChannel) -> Self {
        match name {
            "first_member" => Self::FirstMember(
                <FirstProtocolRequestStream as fidl::endpoints::RequestStream>::from_channel(
                    _channel,
                ),
            ),
            "second_member" => Self::SecondMember(
                <FirstProtocolRequestStream as fidl::endpoints::RequestStream>::from_channel(
                    _channel,
                ),
            ),
            _ => panic!("no such member protocol name for service MultiHomogeneousMemberService"),
        }
    }

    fn member_names() -> &'static [&'static str] {
        &["first_member", "second_member"]
    }
}
#[cfg(target_os = "fuchsia")]
pub struct MultiHomogeneousMemberServiceProxy(Box<dyn fidl::endpoints::MemberOpener>);

#[cfg(target_os = "fuchsia")]
impl fidl::endpoints::UnifiedServiceProxy for MultiHomogeneousMemberServiceProxy {
    type Service = MultiHomogeneousMemberServiceMarker;

    fn from_member_opener(opener: Box<dyn fidl::endpoints::MemberOpener>) -> Self {
        Self(opener)
    }
}

#[cfg(target_os = "fuchsia")]
impl MultiHomogeneousMemberServiceProxy {
    pub fn first_member(&self) -> Result<FirstProtocolProxy, fidl::Error> {
        let (proxy, server) = zx::Channel::create().map_err(fidl::Error::ChannelPairCreate)?;
        self.0.open_member("first_member", server)?;
        let proxy = fidl::AsyncChannel::from_channel(proxy).map_err(fidl::Error::AsyncChannel)?;
        Ok(FirstProtocolProxy::new(proxy))
    }
    pub fn second_member(&self) -> Result<FirstProtocolProxy, fidl::Error> {
        let (proxy, server) = zx::Channel::create().map_err(fidl::Error::ChannelPairCreate)?;
        self.0.open_member("second_member", server)?;
        let proxy = fidl::AsyncChannel::from_channel(proxy).map_err(fidl::Error::AsyncChannel)?;
        Ok(FirstProtocolProxy::new(proxy))
    }
}
