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

#![allow(
	deprecated, // FIDL Impl struct pattern is referenced internally
	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},
        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, PartialEq, PartialOrd)]
pub enum SimpleUnion {
    A(i32),
    B(f32),
}
fidl_xunion! {
    name: SimpleUnion,
    members: [
        A {
            ty: i32,
            ordinal: 1,
        },
        B {
            ty: f32,
            ordinal: 2,
        },
    ],
    strict_value: true,
}

#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct StructWithNullableString {
    pub val: Option<String>,
}

fidl_struct! {
  name: StructWithNullableString,
  members: [
    val {
      ty: Option<String>,
      offset_v1: 0,
    },
  ],
  padding: [],
  size_v1: 16,
  align_v1: 8,
}

#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct StructWithNullableVector {
    pub val: Option<Vec<i32>>,
}

fidl_struct! {
  name: StructWithNullableVector,
  members: [
    val {
      ty: Option<Vec<i32>>,
      offset_v1: 0,
    },
  ],
  padding: [],
  size_v1: 16,
  align_v1: 8,
}

#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct StructWithNullableHandle {
    pub val: Option<fidl::Vmo>,
}

fidl_struct! {
  name: StructWithNullableHandle,
  members: [
    val {
      ty: Option<fidl::Vmo>,
      offset_v1: 0,
      handle_metadata: {
        handle_subtype: fidl::ObjectType::VMO,
        handle_rights: fidl::Rights::from_bits_const(2147483648).unwrap(),
      },
    },
  ],
  padding: [],
  size_v1: 4,
  align_v1: 4,
}

#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct StructWithNullableProtocol {
    pub val: Option<fidl::endpoints::ClientEnd<SimpleProtocolMarker>>,
}

fidl_struct! {
  name: StructWithNullableProtocol,
  members: [
    val {
      ty: Option<fidl::endpoints::ClientEnd<SimpleProtocolMarker>>,
      offset_v1: 0,
      handle_metadata: {
        handle_subtype: fidl::ObjectType::CHANNEL,
        handle_rights: fidl::Rights::CHANNEL_DEFAULT,
      },
    },
  ],
  padding: [],
  size_v1: 4,
  align_v1: 4,
}

#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct StructWithNullableRequest {
    pub val: Option<fidl::endpoints::ServerEnd<SimpleProtocolMarker>>,
}

fidl_struct! {
  name: StructWithNullableRequest,
  members: [
    val {
      ty: Option<fidl::endpoints::ServerEnd<SimpleProtocolMarker>>,
      offset_v1: 0,
      handle_metadata: {
        handle_subtype: fidl::ObjectType::CHANNEL,
        handle_rights: fidl::Rights::CHANNEL_DEFAULT,
      },
    },
  ],
  padding: [],
  size_v1: 4,
  align_v1: 4,
}

#[derive(
    Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, zerocopy::AsBytes, zerocopy::FromBytes,
)]
#[repr(C)]
pub struct Int32Wrapper {
    pub val: i32,
}

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

#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct StructWithNullableStruct {
    pub val: Option<Box<Int32Wrapper>>,
}

fidl_struct! {
  name: StructWithNullableStruct,
  members: [
    val {
      ty: Option<Box<Int32Wrapper>>,
      offset_v1: 0,
    },
  ],
  padding: [],
  size_v1: 8,
  align_v1: 8,
}

#[derive(Debug, Clone, PartialEq, PartialOrd)]
pub struct StructWithNullableUnion {
    pub val: Option<Box<SimpleUnion>>,
}

fidl_struct! {
  name: StructWithNullableUnion,
  members: [
    val {
      ty: Option<Box<SimpleUnion>>,
      offset_v1: 0,
    },
  ],
  padding: [],
  size_v1: 24,
  align_v1: 8,
}

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

impl fidl::endpoints::ServiceMarker for SimpleProtocolMarker {
    type Proxy = SimpleProtocolProxy;
    type RequestStream = SimpleProtocolRequestStream;
    const DEBUG_NAME: &'static str = "(anonymous) SimpleProtocol";
}

pub trait SimpleProtocolProxyInterface: Send + Sync {
    type AddResponseFut: std::future::Future<Output = Result<(i32), fidl::Error>> + Send;
    fn add(&self, a: i32, b: i32) -> Self::AddResponseFut;
}

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

#[cfg(target_os = "fuchsia")]
impl SimpleProtocolSynchronousProxy {
    pub fn new(channel: fidl::Channel) -> Self {
        Self { client: fidl::client::sync::Client::new(channel) }
    }

    pub fn into_channel(self) -> fidl::Channel {
        self.client.into_channel()
    }
    pub fn add(
        &mut self,
        mut a: i32,
        mut b: i32,
        ___deadline: zx::Time,
    ) -> Result<(i32), fidl::Error> {
        let _value: (i32,) =
            self.client.send_query(&mut (a, b), 0x113010d7832f175d, ___deadline)?;
        Ok(_value.0)
    }
}

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

impl fidl::endpoints::Proxy for SimpleProtocolProxy {
    type Service = SimpleProtocolMarker;

    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 SimpleProtocolProxy {
    /// Create a new Proxy for SimpleProtocol
    pub fn new(channel: fidl::AsyncChannel) -> Self {
        let service_name = <SimpleProtocolMarker 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 SimpleProtocol protocol
    ///
    /// # Panics
    ///
    /// Panics if the event stream was already taken.
    pub fn take_event_stream(&self) -> SimpleProtocolEventStream {
        SimpleProtocolEventStream { event_receiver: self.client.take_event_receiver() }
    }
    pub fn add(&self, mut a: i32, mut b: i32) -> fidl::client::QueryResponseFut<(i32)> {
        SimpleProtocolProxyInterface::add(self, a, b)
    }
}

impl SimpleProtocolProxyInterface for SimpleProtocolProxy {
    type AddResponseFut = fidl::client::QueryResponseFut<(i32)>;
    fn add(&self, mut a: i32, mut b: i32) -> Self::AddResponseFut {
        fn transform(result: Result<(i32,), fidl::Error>) -> Result<(i32), fidl::Error> {
            result.map(|_value| _value.0)
        }
        let send_result = self.client.call_send_raw_query(&mut (a, b), 0x113010d7832f175d);
        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 SimpleProtocolEventStream {
    event_receiver: fidl::client::EventReceiver,
}

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

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

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

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

impl SimpleProtocolEvent {}

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

impl<'a> SimpleProtocolServerSender<'a> {
    pub fn new(channel: &'a fidl::Channel) -> Self {
        Self { channel }
    }
    pub fn send_add_response(
        &self,
        txid: fidl::client::Txid,
        mut sum: i32,
    ) -> Result<(), fidl::Error> {
        fidl::encoding::with_tls_encode_buf(|bytes_, handles_| {
            SimpleProtocolEncoder::encode_add_response(bytes_, handles_, txid.as_raw_id(), sum)?;
            self.channel
                .write_etc(&*bytes_, &mut *handles_)
                .map_err(fidl::Error::ServerResponseWrite)?;
            Ok(())
        })
    }
}

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

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

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

impl fidl::endpoints::RequestStream for SimpleProtocolRequestStream {
    type Service = SimpleProtocolMarker;

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

    /// ControlHandle for the remote connection
    fn control_handle(&self) -> Self::ControlHandle {
        SimpleProtocolControlHandle { 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 SimpleProtocolRequestStream {
    type Item = Result<SimpleProtocolRequest, 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 SimpleProtocolRequestStream 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() {
                0x113010d7832f175d => {
                    let mut req: (i32, i32) = fidl::encoding::Decodable::new_empty();
                    fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.nullable/SimpleProtocolAddRequest");
                    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 = SimpleProtocolControlHandle { inner: this.inner.clone() };

                    Ok(SimpleProtocolRequest::Add {
                        a: req.0,
                        b: req.1,
                        responder: SimpleProtocolAddResponder {
                            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:
                        <SimpleProtocolMarker 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 SimpleProtocolRequest instead")]
pub enum SimpleProtocolRequestMessage {
    Add { a: i32, b: i32, tx_id: fidl::client::Txid },
}

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

        match header.ordinal() {
            0x113010d7832f175d => {
                let mut out_tuple: (i32, i32) = fidl::encoding::Decodable::new_empty();
                fidl::duration_begin!("fidl", "decode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.nullable/SimpleProtocolAddRequest");
                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(SimpleProtocolRequestMessage::Add {
                    a: out_tuple.0,
                    b: out_tuple.1,
                    tx_id: header.tx_id().into(),
                })
            }
            _ => Err(fidl::Error::UnknownOrdinal {
                ordinal: header.ordinal(),
                service_name: <SimpleProtocolMarker as fidl::endpoints::ServiceMarker>::DEBUG_NAME,
            }),
        }
    }
}
#[derive(Debug)]
pub enum SimpleProtocolRequest {
    Add { a: i32, b: i32, responder: SimpleProtocolAddResponder },
}

impl SimpleProtocolRequest {
    #[allow(irrefutable_let_patterns)]
    pub fn into_add(self) -> Option<(i32, i32, SimpleProtocolAddResponder)> {
        if let SimpleProtocolRequest::Add { a, b, responder } = self {
            Some((a, b, responder))
        } else {
            None
        }
    }

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

pub struct SimpleProtocolEncoder;

impl SimpleProtocolEncoder {
    pub fn encode_add_request<'a>(
        out_bytes: &'a mut Vec<u8>,
        out_handles: &'a mut Vec<fidl::HandleDisposition<'static>>,
        tx_id: u32,
        mut in_a: i32,
        mut in_b: i32,
    ) -> Result<(), fidl::Error> {
        let header = fidl::encoding::TransactionHeader::new(tx_id, 0x113010d7832f175d);
        let mut body = (in_a, in_b);
        let mut msg = fidl::encoding::TransactionMessage { header, body: &mut body };
        fidl::duration_begin!("fidl", "encode", "bindings" => _FIDL_TRACE_BINDINGS_RUST, "name" => "fidl.test.nullable/SimpleProtocolAddRequest");
        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_add_response<'a>(
        out_bytes: &'a mut Vec<u8>,
        out_handles: &'a mut Vec<fidl::HandleDisposition<'static>>,
        tx_id: u32,
        mut in_sum: i32,
    ) -> Result<(), fidl::Error> {
        let header = fidl::encoding::TransactionHeader::new(tx_id, 0x113010d7832f175d);
        let mut body = (in_sum,);
        let mut msg = fidl::encoding::TransactionMessage { header, body: &mut body };

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

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

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

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

impl SimpleProtocolAddResponder {
    pub fn control_handle(&self) -> &SimpleProtocolControlHandle {
        &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 sum: i32) -> Result<(), fidl::Error> {
        let r = self.send_raw(sum);
        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 sum: i32) -> Result<(), fidl::Error> {
        let r = self.send_raw(sum);
        self.drop_without_shutdown();
        r
    }

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

        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.nullable/SimpleProtocolAddResponse");
            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(())
        })
    }
}
