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

#![feature(futures_api, pin, arbitrary_self_types, nll)]
#![allow(warnings)]

extern crate fuchsia_async;
extern crate fuchsia_zircon as zx;
#[macro_use]
extern crate fidl;
#[macro_use]
extern crate futures;
use fidl::encoding::{Encodable, Decodable};
use futures::{Future, Stream, StreamExt};
use std::ops::Deref;



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

impl fidl::endpoints::ServiceMarker for SwitchingOrdinalsMarker {
	type Proxy = SwitchingOrdinalsProxy;
	type RequestStream = SwitchingOrdinalsRequestStream;
	const NAME: &'static str = "";
}

pub trait SwitchingOrdinalsProxyInterface: Send + Sync {
	fn ordinal_five(&self,
	)-> Result<(), fidl::Error>;
	fn only_generated_ordinal(&self,
	)-> Result<(), fidl::Error>;
	type EventOrdinalFifteenResponseFut: Future<Output = Result<(), fidl::Error>> + Send;
	type EventOnlyGeneratedOrdinalResponseFut: Future<Output = Result<(), fidl::Error>> + Send;
}

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

impl SwitchingOrdinalsSynchronousProxy {
	pub fn new(channel: zx::Channel) -> Self {
		Self { client: fidl::client::sync::Client::new(channel) }
	}

	pub fn into_channel(self) -> zx::Channel {
		self.client.into_channel()
	}
	pub fn ordinal_five(&mut self,) -> Result<(), fidl::Error> {self.client.send(&mut (),
				2005164903,
			)}
	pub fn only_generated_ordinal(&mut self,) -> Result<(), fidl::Error> {self.client.send(&mut (),
				667506719,
			)}
}

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

impl fidl::endpoints::Proxy for SwitchingOrdinalsProxy {
	fn from_channel(inner: ::fuchsia_async::Channel) -> Self {
		Self::new(inner)
	}
}

impl Deref for SwitchingOrdinalsProxy {
	type Target = fidl::client::Client;

	fn deref(&self) -> &Self::Target {
		&self.client
	}
}

/// Proxy object for communicating with interface SwitchingOrdinals
impl SwitchingOrdinalsProxy {
        /// Create a new Proxy for SwitchingOrdinals
   pub fn new(channel: ::fuchsia_async::Channel) -> Self {
		Self { client: fidl::client::Client::new(channel) }
	}

	/// Attempt to convert the Proxy back into a channel.
	///
	/// This will only succeed if there are no active clones of this Proxy
	/// and no currently-alive EventStream or response futures that came from
	/// this Proxy.
	pub fn into_channel(self) -> Result<::fuchsia_async::Channel, Self> {
		self.client.into_channel().map_err(|client| Self { client })
	}

        /// Get a Stream of events from the remote end of the SwitchingOrdinals interface
	pub fn take_event_stream(&self) -> SwitchingOrdinalsEventStream {
		SwitchingOrdinalsEventStream {
			event_receiver: self.client.take_event_receiver(),
		}
	}
	pub fn ordinal_five(&self,
	)-> Result<(), fidl::Error> {
		SwitchingOrdinalsProxyInterface::ordinal_five(self,
		)
	}
	pub fn only_generated_ordinal(&self,
	)-> Result<(), fidl::Error> {
		SwitchingOrdinalsProxyInterface::only_generated_ordinal(self,
		)
	}
}

impl SwitchingOrdinalsProxyInterface for SwitchingOrdinalsProxy {
	fn ordinal_five(&self,
	)-> Result<(), fidl::Error> {
		self.client.send(&mut (), 2005164903)
	}
	fn only_generated_ordinal(&self,
	)-> Result<(), fidl::Error> {
		self.client.send(&mut (), 667506719)
	}
	type EventOrdinalFifteenResponseFut = fidl::client::QueryResponseFut<()>;
	type EventOnlyGeneratedOrdinalResponseFut = fidl::client::QueryResponseFut<()>;}

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

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

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

impl Stream for SwitchingOrdinalsEventStream {
	type Item = Result<SwitchingOrdinalsEvent, fidl::Error>;

	fn poll_next(mut self: ::std::pin::Pin<&mut Self>, lw: &futures::task::LocalWaker)
		-> futures::Poll<Option<Self::Item>>
	{
		let mut buf = match ready!(self.event_receiver.poll_next_unpin(lw)?) {
			Some(buf) => buf,
			None => return futures::Poll::Ready(None),
		};
		let (bytes, handles) = buf.split_mut();
		let (tx_header, body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
		futures::Poll::Ready(Some(match tx_header.ordinal {
			1467258273 | 15 => {
				let mut out_tuple: () = fidl::encoding::Decodable::new_empty();
				fidl::encoding::Decoder::decode_into(body_bytes, handles, &mut out_tuple)?;
				Ok((
					SwitchingOrdinalsEvent::EventOrdinalFifteen {}
				))
			}
			2146190926 | 2146190926 => {
				let mut out_tuple: () = fidl::encoding::Decodable::new_empty();
				fidl::encoding::Decoder::decode_into(body_bytes, handles, &mut out_tuple)?;
				Ok((
					SwitchingOrdinalsEvent::EventOnlyGeneratedOrdinal {}
				))
			}
			_ => Err(fidl::Error::UnknownOrdinal {
				ordinal: tx_header.ordinal,
				service_name: <SwitchingOrdinalsMarker as fidl::endpoints::ServiceMarker>::NAME,
			})
		}))
	}
}

#[derive(Debug)]
pub enum SwitchingOrdinalsEvent {
	
	
	
	
	EventOrdinalFifteen {
		
	},
	
	EventOnlyGeneratedOrdinal {
		
	},}

#[deprecated(note = "use SwitchingOrdinalsRequestStream instead")]
pub trait SwitchingOrdinals {
	type OnOpenFut: Future<Output = ()> + Send;
	fn on_open(&mut self, control_handle: SwitchingOrdinalsControlHandle) -> Self::OnOpenFut;
	type OrdinalFiveFut: Future<Output = ()> + Send;
	fn ordinal_five (&mut self,
		control_handle: SwitchingOrdinalsControlHandle
	) -> Self::OrdinalFiveFut;
	
	type OnlyGeneratedOrdinalFut: Future<Output = ()> + Send;
	fn only_generated_ordinal (&mut self,
		control_handle: SwitchingOrdinalsControlHandle
	) -> Self::OnlyGeneratedOrdinalFut;
	

	fn serve(mut self, channel: ::fuchsia_async::Channel)
		-> SwitchingOrdinalsServer<Self>
	where Self: Sized
	{
		let inner = ::std::sync::Arc::new(fidl::ServeInner::new(channel));
		let on_open_fut = self.on_open(
			SwitchingOrdinalsControlHandle {
				inner: inner.clone(),
			}
		);
		SwitchingOrdinalsServer {
			server: self,
			inner: inner.clone(),
			msg_buf: zx::MessageBuf::new(),
			on_open_fut: Some(on_open_fut),ordinal_five_futures: futures::stream::FuturesUnordered::new(),only_generated_ordinal_futures: futures::stream::FuturesUnordered::new(),
		}
	}
}

pub struct SwitchingOrdinalsServer<T: SwitchingOrdinals> {
	server: T,
	inner: ::std::sync::Arc<fidl::ServeInner>,
	msg_buf: zx::MessageBuf,
	on_open_fut: Option<T::OnOpenFut>,ordinal_five_futures: futures::stream::FuturesUnordered<T::OrdinalFiveFut>,only_generated_ordinal_futures: futures::stream::FuturesUnordered<T::OnlyGeneratedOrdinalFut>,
}

// Safety: only the OnOpen fut is held directly, so it's the only one that
// is projected to, so it's the only one that needs to be Unpin for the Impl
// struct to be Unpin.
impl<T: SwitchingOrdinals> ::std::marker::Unpin for SwitchingOrdinalsServer<T>
where T::OnOpenFut: ::std::marker::Unpin,
{}

impl<T: SwitchingOrdinals> SwitchingOrdinalsServer<T> {
	pub fn control_handle(&self) -> SwitchingOrdinalsControlHandle {
		SwitchingOrdinalsControlHandle {
			inner: self.inner.clone(),
		}
	}
}

impl<T: SwitchingOrdinals> futures::Future for SwitchingOrdinalsServer<T> {
	type Output = Result<(), fidl::Error>;

	fn poll(
		mut self: ::std::pin::Pin<&mut Self>,
		lw: &::futures::task::LocalWaker,
	) -> futures::Poll<Self::Output> {
		// safety: the only potentially !Unpin field is on_open_fut, which we make sure
		// isn't moved below
		let this = unsafe { ::std::pin::Pin::get_unchecked_mut(self) };
		loop {
		let mut made_progress_this_loop_iter = false;

		if this.inner.poll_shutdown(lw) {
			return futures::Poll::Ready(Ok(()));
		}

		unsafe {
			// Safety: ensure that on_open isn't moved
			let completed_on_open = if let Some(on_open_fut) = &mut this.on_open_fut {
				match Future::poll(::std::pin::Pin::new_unchecked(on_open_fut), lw) {
					futures::Poll::Ready(()) => true,
					futures::Poll::Pending => false,
				}
			} else {
				false
			};

			if completed_on_open {
				made_progress_this_loop_iter = true;
				this.on_open_fut = None;
			}
		}match this.ordinal_five_futures.poll_next_unpin(lw) {
			futures::Poll::Ready(Some(())) => made_progress_this_loop_iter = true,
			_ => {},
		}match this.only_generated_ordinal_futures.poll_next_unpin(lw) {
			futures::Poll::Ready(Some(())) => made_progress_this_loop_iter = true,
			_ => {},
		}

		match this.inner.channel().recv_from(&mut this.msg_buf, lw) {
			futures::Poll::Ready(Ok(())) => {},
			futures::Poll::Pending => {
				if !made_progress_this_loop_iter {
					return futures::Poll::Pending;
				} else {
					continue;
				}
			}
			futures::Poll::Ready(Err(zx::Status::PEER_CLOSED)) => {
				return futures::Poll::Ready(Ok(()));
			}
			futures::Poll::Ready(Err(e)) =>
				return futures::Poll::Ready(Err(fidl::Error::ServerRequestRead(e))),
		}

		{
			// A message has been received from the channel
			let (bytes, handles) = this.msg_buf.split_mut();
			let (header, body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;

			match header.ordinal {
					2005164903 | 5 => {
						let mut req: () = fidl::encoding::Decodable::new_empty();
						fidl::encoding::Decoder::decode_into(body_bytes, handles, &mut req)?;
						let control_handle = SwitchingOrdinalsControlHandle {
							inner: this.inner.clone(),
						};
						this.ordinal_five_futures.push(
							this.server.ordinal_five(control_handle)
						);
					}
					667506719 | 667506719 => {
						let mut req: () = fidl::encoding::Decodable::new_empty();
						fidl::encoding::Decoder::decode_into(body_bytes, handles, &mut req)?;
						let control_handle = SwitchingOrdinalsControlHandle {
							inner: this.inner.clone(),
						};
						this.only_generated_ordinal_futures.push(
							this.server.only_generated_ordinal(control_handle)
						);
					}
				// TODO(cramertj) handle control/fileio messages
				_ => return futures::Poll::Ready(Err(fidl::Error::UnknownOrdinal {
					ordinal: header.ordinal,
					service_name: "unknown fidl", // TODO(cramertj)
				})),
			}
		}
		this.msg_buf.clear();
	}}
}

/// A Stream of incoming requests for SwitchingOrdinals
pub struct SwitchingOrdinalsRequestStream {
	inner: ::std::sync::Arc<fidl::ServeInner>,
	msg_buf: Option<zx::MessageBuf>,
}

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

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

impl fidl::endpoints::RequestStream for SwitchingOrdinalsRequestStream {
	/// Consume a channel to make a SwitchingOrdinalsRequestStream
	fn from_channel(channel: ::fuchsia_async::Channel) -> Self {
		Self {
			inner: ::std::sync::Arc::new(fidl::ServeInner::new(channel)),
			msg_buf: Some(zx::MessageBuf::new()),
		}
	}

   /// ControlHandle for the remote connection
	type ControlHandle = SwitchingOrdinalsControlHandle;

   /// ControlHandle for the remote connection
	fn control_handle(&self) -> Self::ControlHandle {
		SwitchingOrdinalsControlHandle { inner: self.inner.clone() }
	}

	fn into_inner(self) -> (::std::sync::Arc<fidl::ServeInner>, Option<zx::MessageBuf>) {
		(self.inner, self.msg_buf)
	}

	fn from_inner(inner: ::std::sync::Arc<fidl::ServeInner>, msg_buf: Option<zx::MessageBuf>) -> Self {
		Self { inner, msg_buf }
	}
}

impl Stream for SwitchingOrdinalsRequestStream {
	type Item = Result<SwitchingOrdinalsRequest, fidl::Error>;

	fn poll_next(mut self: ::std::pin::Pin<&mut Self>, lw: &::futures::task::LocalWaker)
		-> ::futures::Poll<Option<Self::Item>>
	{
		let this = &mut *self;
		if this.inner.poll_shutdown(lw) {
			this.msg_buf = None;
			return futures::Poll::Ready(None);
		}
		let msg_buf = this.msg_buf.as_mut()
								.expect("polled SwitchingOrdinalsRequestStream after completion");
		match this.inner.channel().recv_from(msg_buf, lw) {
			futures::Poll::Ready(Ok(())) => {},
			futures::Poll::Pending => return futures::Poll::Pending,
			futures::Poll::Ready(Err(zx::Status::PEER_CLOSED)) => {
				this.msg_buf = None;
				return futures::Poll::Ready(None)
			},
			futures::Poll::Ready(Err(e)) =>
				return futures::Poll::Ready(Some(Err(fidl::Error::ServerRequestRead(e)))),
		}

		let res = {
			// A message has been received from the channel
			let (bytes, handles) = msg_buf.split_mut();
			let (header, body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;

			match header.ordinal {
				2005164903 | 5 => {
					let mut req: () = fidl::encoding::Decodable::new_empty();
					fidl::encoding::Decoder::decode_into(body_bytes, handles, &mut req)?;
					let control_handle = SwitchingOrdinalsControlHandle {
						inner: this.inner.clone(),
					};

					SwitchingOrdinalsRequest::OrdinalFive {control_handle,}
				}
				667506719 | 667506719 => {
					let mut req: () = fidl::encoding::Decodable::new_empty();
					fidl::encoding::Decoder::decode_into(body_bytes, handles, &mut req)?;
					let control_handle = SwitchingOrdinalsControlHandle {
						inner: this.inner.clone(),
					};

					SwitchingOrdinalsRequest::OnlyGeneratedOrdinal {control_handle,}
				}
				_ => return futures::Poll::Ready(Some(Err(fidl::Error::UnknownOrdinal {
					ordinal: header.ordinal,
					service_name: <SwitchingOrdinalsMarker as fidl::endpoints::ServiceMarker>::NAME,
				}))),
			}
		};

		msg_buf.clear();
		futures::Poll::Ready(Some(Ok(res)))
	}
}
pub enum SwitchingOrdinalsRequest {
	OrdinalFive {
		control_handle: SwitchingOrdinalsControlHandle,},
	OnlyGeneratedOrdinal {
		control_handle: SwitchingOrdinalsControlHandle,},
}

#[deprecated(note = "use SwitchingOrdinalsRequestStream instead")]
pub struct SwitchingOrdinalsImpl<
	State,
OnOpen: FnMut(&mut State, SwitchingOrdinalsControlHandle) -> OnOpenFut,
OnOpenFut: Future<Output = ()> + Send,
	OrdinalFive: FnMut(&mut State,SwitchingOrdinalsControlHandle) -> OrdinalFiveFut,
	OrdinalFiveFut: Future<Output = ()> + Send,
	OnlyGeneratedOrdinal: FnMut(&mut State,SwitchingOrdinalsControlHandle) -> OnlyGeneratedOrdinalFut,
	OnlyGeneratedOrdinalFut: Future<Output = ()> + Send,
> {
	pub state: State,
	pub on_open: OnOpen,
	pub ordinal_five: OrdinalFive,
	pub only_generated_ordinal: OnlyGeneratedOrdinal,
}

// Unpin is never projected for the Impl struct
impl<
	State,
OnOpen: FnMut(&mut State, SwitchingOrdinalsControlHandle) -> OnOpenFut,
OnOpenFut: Future<Output = ()> + Send,
	OrdinalFive: FnMut(&mut State,SwitchingOrdinalsControlHandle) -> OrdinalFiveFut,
	OrdinalFiveFut: Future<Output = ()> + Send,
	OnlyGeneratedOrdinal: FnMut(&mut State,SwitchingOrdinalsControlHandle) -> OnlyGeneratedOrdinalFut,
	OnlyGeneratedOrdinalFut: Future<Output = ()> + Send,
> ::std::marker::Unpin for SwitchingOrdinalsImpl<State, OnOpen, OnOpenFut,
	OrdinalFive,
	OrdinalFiveFut,
	OnlyGeneratedOrdinal,
	OnlyGeneratedOrdinalFut,
>
{}

impl<
	State,
OnOpen: FnMut(&mut State, SwitchingOrdinalsControlHandle) -> OnOpenFut,
OnOpenFut: Future<Output = ()> + Send,
	OrdinalFive: FnMut(&mut State,SwitchingOrdinalsControlHandle) -> OrdinalFiveFut,
	OrdinalFiveFut: Future<Output = ()> + Send,
	OnlyGeneratedOrdinal: FnMut(&mut State,SwitchingOrdinalsControlHandle) -> OnlyGeneratedOrdinalFut,
	OnlyGeneratedOrdinalFut: Future<Output = ()> + Send,
> SwitchingOrdinals for SwitchingOrdinalsImpl<State, OnOpen, OnOpenFut,
	OrdinalFive,
	OrdinalFiveFut,
	OnlyGeneratedOrdinal,
	OnlyGeneratedOrdinalFut,
>
{
	type OnOpenFut = OnOpenFut;
	fn on_open(&mut self, response_chan: SwitchingOrdinalsControlHandle) -> Self::OnOpenFut {
		(self.on_open)(&mut self.state, response_chan)
	}
	type OrdinalFiveFut = OrdinalFiveFut;
	fn ordinal_five (&mut self,
		response_chan: SwitchingOrdinalsControlHandle
	) -> Self::OrdinalFiveFut
	{
		(self.ordinal_five)(
			&mut self.state,
			response_chan
		)
	}
	
	type OnlyGeneratedOrdinalFut = OnlyGeneratedOrdinalFut;
	fn only_generated_ordinal (&mut self,
		response_chan: SwitchingOrdinalsControlHandle
	) -> Self::OnlyGeneratedOrdinalFut
	{
		(self.only_generated_ordinal)(
			&mut self.state,
			response_chan
		)
	}
	
}

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

impl Deref for SwitchingOrdinalsControlHandle {
        type Target = ::std::sync::Arc<fidl::ServeInner>;

	fn deref(&self) -> &Self::Target {
		&self.inner
	}
}


impl SwitchingOrdinalsControlHandle {
	pub fn shutdown(&self) {
		self.inner.shutdown()
	}
	pub fn send_event_ordinal_fifteen(&self) -> Result<(), fidl::Error> {
		let header = fidl::encoding::TransactionHeader {
			tx_id: 0,
			flags: 0,
			ordinal: 1467258273,
		};

		let mut response = ();

		let mut msg = fidl::encoding::TransactionMessage {
			header,
			body: &mut response,
		};

		let (bytes, handles) = (&mut vec![], &mut vec![]);
		fidl::encoding::Encoder::encode(bytes, handles, &mut msg)?;
		self.inner.channel().write(&*bytes, &mut *handles).map_err(fidl::Error::ServerResponseWrite)?;
		Ok(())
	}
	
	pub fn send_event_only_generated_ordinal(&self) -> Result<(), fidl::Error> {
		let header = fidl::encoding::TransactionHeader {
			tx_id: 0,
			flags: 0,
			ordinal: 2146190926,
		};

		let mut response = ();

		let mut msg = fidl::encoding::TransactionMessage {
			header,
			body: &mut response,
		};

		let (bytes, handles) = (&mut vec![], &mut vec![]);
		fidl::encoding::Encoder::encode(bytes, handles, &mut msg)?;
		self.inner.channel().write(&*bytes, &mut *handles).map_err(fidl::Error::ServerResponseWrite)?;
		Ok(())
	}
	}

/* beginning of response types */
