// 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},
        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, 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 r#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 {
        let service_name = <SimpleProtocolMarker 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#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 r#add(&self, mut a: i32, mut b: i32) -> fidl::client::QueryResponseFut<(i32)> {
        SimpleProtocolProxyInterface::r#add(self, a, b)
    }
}

impl SimpleProtocolProxyInterface for SimpleProtocolProxy {
    type AddResponseFut = fidl::client::QueryResponseFut<(i32)>;
    fn r#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(())
        })
    }
}
