// 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;
bitflags! {
    /// strict bits comment #1
    ///
    /// strict bits comment #2
    pub struct MyStrictBits: u32 {
        /// MY_FIRST_BIT member comment #1
        ///
        /// MY_FIRST_BIT member comment #3
        const MyFirstBit = 1;
        /// MY_OTHER_BIT member comment #1
        ///
        /// MY_OTHER_BIT member comment #3
        const MyOtherBit = 2;
    }
}
fidl_strict_bits! {
    name: MyStrictBits,
    prim_ty: u32,
}

bitflags! {
    /// flexible bits comment #1
    ///
    /// flexible bits comment #2
    pub struct MyFlexibleBits: u32 {
        /// MY_FIRST_BIT member comment #1
        ///
        /// MY_FIRST_BIT member comment #3
        const MyFirstBit = 1;
        /// MY_OTHER_BIT member comment #1
        ///
        /// MY_OTHER_BIT member comment #3
        const MyOtherBit = 2;
    }
}
fidl_flexible_bits! {
    name: MyFlexibleBits,
    prim_ty: u32,
}

/// const comment #1
///
/// const comment #3
pub const C: i32 = 4;

/// strict enum comment #1.
///
/// strict enum comment #2.
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
#[repr(u32)]
pub enum MyStrictEnum {
    /// FOO member comment #1
    ///
    /// FOO member comment #3
    Foo = 1,
    /// BAR member comment #1
    ///
    /// BAR member comment #3
    Bar = 2,
}
fidl_strict_enum! {
    name: MyStrictEnum,
    prim_ty: u32,
    members: [
        Foo { value: 1, },
        Bar { value: 2, },
    ],
}

/// flexible enum comment #1.
///
/// flexible enum comment #2.
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
#[non_exhaustive]
pub enum MyFlexibleEnum {
    /// FOO member comment #1
    ///
    /// FOO member comment #3
    Foo,
    /// BAR member comment #1
    ///
    /// BAR member comment #3
    Bar,
    #[deprecated = "Use `MyFlexibleEnum::unknown()` to construct and `MyFlexibleEnumUnknown!()` to exhaustively match."]
    #[doc(hidden)]
    __Unknown(u32),
}
/// Pattern that matches an unknown MyFlexibleEnum member.
#[macro_export]
macro_rules! MyFlexibleEnumUnknown {
    () => {
        _
    };
}
fidl_flexible_enum! {
    name: MyFlexibleEnum,
    prim_ty: u32,
    members: [
        Foo { value: 1, },
        Bar { value: 2, },
    ],
    unknown_member: __Unknown,
    default_unknown_value: 0xffffffff,
}

/// strict union comment #1
///
/// strict union comment #3
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub enum StrictUnion {
    /// union member comment #1
    ///
    /// union member comment #3
    Field(i32),
}
fidl_xunion! {
    name: StrictUnion,
    members: [
        Field {
            ty: i32,
            ordinal: 1,
        },
    ],
    strict_value: true,
}

/// flexible union comment #1
///
/// flexible union comment #3
#[derive(Debug, Clone, PartialEq)]
pub enum FlexibleUnion {
    /// union member comment #1
    ///
    /// union member comment #3
    Field(i32),
    #[deprecated = "Use `FlexibleUnion::unknown()` to construct and `FlexibleUnionUnknown!()` to exhaustively match."]
    #[doc(hidden)]
    __Unknown { ordinal: u64, bytes: Vec<u8> },
}
/// Pattern that matches an unknown FlexibleUnion member.
#[macro_export]
macro_rules! FlexibleUnionUnknown {
    () => {
        _
    };
}
fidl_xunion! {
    name: FlexibleUnion,
    members: [
        Field {
            ty: i32,
            ordinal: 1,
        },
    ],
    value_unknown_member: __Unknown,
}

/// struct comment #1
///
/// struct comment #3
#[derive(
    Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, zerocopy::AsBytes, zerocopy::FromBytes,
)]
#[repr(C)]
pub struct Struct {
    /// struct member comment #1
    ///
    /// struct member comment #3
    pub field: i32,
}

fidl_struct_copy! {
  name: Struct,
  members: [
    field {
      ty: i32,
      offset_v1: 0,
    },
  ],
  padding: [],
  size_v1: 4,
  align_v1: 4,
}

/// table comment #1
///
/// table comment #3
#[derive(Debug, Clone, PartialEq)]
pub struct Table {
    /// table field comment #1
    ///
    /// table field comment #3
    pub field: Option<i32>,
    /// (FIDL-generated) Unknown fields encountered during decoding, stored as a
    /// map from ordinals to raw data. The `Some` case is always nonempty.
    pub unknown_data: Option<std::collections::BTreeMap<u64, Vec<u8>>>,
    #[deprecated = "Use `..Table::EMPTY` to construct and `..` to match."]
    #[doc(hidden)]
    pub __non_exhaustive: (),
}

fidl_table! {
  name: Table,
  members: [
    field {
      ty: i32,
      ordinal: 1,
    },
  ],
  value_unknown_member: unknown_data,
}

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

impl fidl::endpoints::ServiceMarker for InterfaceMarker {
    type Proxy = InterfaceProxy;
    type RequestStream = InterfaceRequestStream;
    const DEBUG_NAME: &'static str = "(anonymous) Interface";
}

pub trait InterfaceProxyInterface: Send + Sync {
    fn r#method(&self) -> Result<(), fidl::Error>;
    type OnEventResponseFut: std::future::Future<Output = Result<(), fidl::Error>> + Send;
}

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

#[cfg(target_os = "fuchsia")]
impl InterfaceSynchronousProxy {
    pub fn new(channel: fidl::Channel) -> Self {
        let service_name = <InterfaceMarker 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()
    }
    /// method comment #1
    ///
    /// method comment #3
    pub fn r#method(&mut self) -> Result<(), fidl::Error> {
        self.client.send(&mut (), 0x5c492542705b4265)
    }
}

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

impl fidl::endpoints::Proxy for InterfaceProxy {
    type Service = InterfaceMarker;

    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 InterfaceProxy {
    /// Create a new Proxy for Interface
    pub fn new(channel: fidl::AsyncChannel) -> Self {
        let service_name = <InterfaceMarker 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 Interface protocol
    ///
    /// # Panics
    ///
    /// Panics if the event stream was already taken.
    pub fn take_event_stream(&self) -> InterfaceEventStream {
        InterfaceEventStream { event_receiver: self.client.take_event_receiver() }
    }
    /// method comment #1
    ///
    /// method comment #3
    pub fn r#method(&self) -> Result<(), fidl::Error> {
        InterfaceProxyInterface::r#method(self)
    }
}

impl InterfaceProxyInterface for InterfaceProxy {
    fn r#method(&self) -> Result<(), fidl::Error> {
        self.client.send(&mut (), 0x5c492542705b4265)
    }
    type OnEventResponseFut = fidl::client::QueryResponseFut<()>;
}

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

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

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

impl futures::Stream for InterfaceEventStream {
    type Item = Result<InterfaceEvent, 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() {
            0x37812b697096f6fa => {
                let mut out_tuple: () = fidl::encoding::Decodable::new_empty();
                fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.doccomments/InterfaceOnEventEvent");
                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((InterfaceEvent::OnEvent {}))
            }
            _ => Err(fidl::Error::UnknownOrdinal {
                ordinal: tx_header.ordinal(),
                service_name: <InterfaceMarker as fidl::endpoints::ServiceMarker>::DEBUG_NAME,
            }),
        }))
    }
}

#[derive(Debug)]
pub enum InterfaceEvent {
    OnEvent {},
}

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

#[allow(deprecated)]
impl<'a> InterfaceServerSender<'a> {
    pub fn new(channel: &'a fidl::Channel) -> Self {
        Self { channel }
    }
    pub fn send_on_event(&self) -> Result<(), fidl::Error> {
        fidl::encoding::with_tls_encode_buf(|bytes_, handles_| {
            InterfaceEncoder::encode_on_event_response(bytes_, handles_)?;
            self.channel
                .write_etc(&*bytes_, &mut *handles_)
                .map_err(fidl::Error::ServerResponseWrite)?;
            Ok(())
        })
    }
}

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

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

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

impl fidl::endpoints::RequestStream for InterfaceRequestStream {
    type Service = InterfaceMarker;

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

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

                    Ok(InterfaceRequest::Method { control_handle })
                }
                _ => Err(fidl::Error::UnknownOrdinal {
                    ordinal: header.ordinal(),
                    service_name: <InterfaceMarker 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 InterfaceRequest instead")]
pub enum InterfaceRequestMessage {
    /// method comment #1
    ///
    /// method comment #3
    Method {},
}

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

        match header.ordinal() {
            0x5c492542705b4265 => {
                let mut out_tuple: () = fidl::encoding::Decodable::new_empty();
                fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.doccomments/InterfaceMethodRequest");
                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(InterfaceRequestMessage::Method {})
            }
            _ => Err(fidl::Error::UnknownOrdinal {
                ordinal: header.ordinal(),
                service_name: <InterfaceMarker as fidl::endpoints::ServiceMarker>::DEBUG_NAME,
            }),
        }
    }
}
/// interface comment #1
///
/// interface comment #3
#[derive(Debug)]
pub enum InterfaceRequest {
    /// method comment #1
    ///
    /// method comment #3
    Method { control_handle: InterfaceControlHandle },
}

impl InterfaceRequest {
    #[allow(irrefutable_let_patterns)]
    pub fn into_method(self) -> Option<(InterfaceControlHandle)> {
        if let InterfaceRequest::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 {
            InterfaceRequest::Method { .. } => "method",
        }
    }
}

pub struct InterfaceEncoder;

impl InterfaceEncoder {
    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, 0x5c492542705b4265);
        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.doccomments/InterfaceMethodRequest");
        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_event_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, 0x37812b697096f6fa);
        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.doccomments/InterfaceOnEventResponse");
        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 InterfaceControlHandle {
    inner: std::sync::Arc<fidl::ServeInner>,
}

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

        let mut msg = fidl::encoding::TransactionMessage {
            header: fidl::encoding::TransactionHeader::new(0, 0x37812b697096f6fa),
            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(())
    }
}

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

#[cfg(target_os = "fuchsia")]
impl fidl::endpoints::UnifiedServiceMarker for ServiceMarker {
    type Proxy = ServiceProxy;
    type Request = ServiceRequest;
    const SERVICE_NAME: &'static str = "fidl.test.doccomments.Service";
}

/// A request for one of the member protocols of Service.
///
/// service comment #1
///
/// service comment #3
#[cfg(target_os = "fuchsia")]
pub enum ServiceRequest {
    /// member comment #1
    ///
    /// member comment #3
    Interface(InterfaceRequestStream),
}

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

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

    fn member_names() -> &'static [&'static str] {
        &["interface"]
    }
}
/// service comment #1
///
/// service comment #3
#[cfg(target_os = "fuchsia")]
pub struct ServiceProxy(Box<dyn fidl::endpoints::MemberOpener>);

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

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

#[cfg(target_os = "fuchsia")]
impl ServiceProxy {
    /// member comment #1
    ///
    /// member comment #3
    pub fn interface(&self) -> Result<InterfaceProxy, fidl::Error> {
        let (proxy, server) = zx::Channel::create().map_err(fidl::Error::ChannelPairCreate)?;
        self.0.open_member("interface", server)?;
        let proxy = fidl::AsyncChannel::from_channel(proxy).map_err(fidl::Error::AsyncChannel)?;
        Ok(InterfaceProxy::new(proxy))
    }
}
