fidl_fuchsia_net_stack/
fidl_fuchsia_net_stack.rs

1// WARNING: This file is machine generated by fidlgen.
2
3#![warn(clippy::all)]
4#![allow(unused_parens, unused_mut, unused_imports, nonstandard_style)]
5
6use bitflags::bitflags;
7use fidl::client::QueryResponseFut;
8use fidl::encoding::{MessageBufFor, ProxyChannelBox, ResourceDialect};
9use fidl::endpoints::{ControlHandle as _, Responder as _};
10pub use fidl_fuchsia_net_stack_common::*;
11use futures::future::{self, MaybeDone, TryFutureExt};
12use zx_status;
13
14#[derive(Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
15pub struct StackBridgeInterfacesRequest {
16    pub interfaces: Vec<u64>,
17    pub bridge: fidl::endpoints::ServerEnd<fidl_fuchsia_net_interfaces_admin::ControlMarker>,
18}
19
20impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect>
21    for StackBridgeInterfacesRequest
22{
23}
24
25#[derive(Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
26pub struct StackSetDhcpClientEnabledRequest {
27    pub id: u64,
28    pub enable: bool,
29}
30
31impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect>
32    for StackSetDhcpClientEnabledRequest
33{
34}
35
36#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
37pub struct LogMarker;
38
39impl fidl::endpoints::ProtocolMarker for LogMarker {
40    type Proxy = LogProxy;
41    type RequestStream = LogRequestStream;
42    #[cfg(target_os = "fuchsia")]
43    type SynchronousProxy = LogSynchronousProxy;
44
45    const DEBUG_NAME: &'static str = "fuchsia.net.stack.Log";
46}
47impl fidl::endpoints::DiscoverableProtocolMarker for LogMarker {}
48
49pub trait LogProxyInterface: Send + Sync {
50    type SetLogPacketsResponseFut: std::future::Future<Output = Result<(), fidl::Error>> + Send;
51    fn r#set_log_packets(&self, enabled: bool) -> Self::SetLogPacketsResponseFut;
52}
53#[derive(Debug)]
54#[cfg(target_os = "fuchsia")]
55pub struct LogSynchronousProxy {
56    client: fidl::client::sync::Client,
57}
58
59#[cfg(target_os = "fuchsia")]
60impl fidl::endpoints::SynchronousProxy for LogSynchronousProxy {
61    type Proxy = LogProxy;
62    type Protocol = LogMarker;
63
64    fn from_channel(inner: fidl::Channel) -> Self {
65        Self::new(inner)
66    }
67
68    fn into_channel(self) -> fidl::Channel {
69        self.client.into_channel()
70    }
71
72    fn as_channel(&self) -> &fidl::Channel {
73        self.client.as_channel()
74    }
75}
76
77#[cfg(target_os = "fuchsia")]
78impl LogSynchronousProxy {
79    pub fn new(channel: fidl::Channel) -> Self {
80        let protocol_name = <LogMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
81        Self { client: fidl::client::sync::Client::new(channel, protocol_name) }
82    }
83
84    pub fn into_channel(self) -> fidl::Channel {
85        self.client.into_channel()
86    }
87
88    /// Waits until an event arrives and returns it. It is safe for other
89    /// threads to make concurrent requests while waiting for an event.
90    pub fn wait_for_event(&self, deadline: zx::MonotonicInstant) -> Result<LogEvent, fidl::Error> {
91        LogEvent::decode(self.client.wait_for_event(deadline)?)
92    }
93
94    /// Dynamically set packet logging.
95    pub fn r#set_log_packets(
96        &self,
97        mut enabled: bool,
98        ___deadline: zx::MonotonicInstant,
99    ) -> Result<(), fidl::Error> {
100        let _response =
101            self.client.send_query::<LogSetLogPacketsRequest, fidl::encoding::EmptyPayload>(
102                (enabled,),
103                0x2176044cba5f378e,
104                fidl::encoding::DynamicFlags::empty(),
105                ___deadline,
106            )?;
107        Ok(_response)
108    }
109}
110
111#[cfg(target_os = "fuchsia")]
112impl From<LogSynchronousProxy> for zx::Handle {
113    fn from(value: LogSynchronousProxy) -> Self {
114        value.into_channel().into()
115    }
116}
117
118#[cfg(target_os = "fuchsia")]
119impl From<fidl::Channel> for LogSynchronousProxy {
120    fn from(value: fidl::Channel) -> Self {
121        Self::new(value)
122    }
123}
124
125#[derive(Debug, Clone)]
126pub struct LogProxy {
127    client: fidl::client::Client<fidl::encoding::DefaultFuchsiaResourceDialect>,
128}
129
130impl fidl::endpoints::Proxy for LogProxy {
131    type Protocol = LogMarker;
132
133    fn from_channel(inner: ::fidl::AsyncChannel) -> Self {
134        Self::new(inner)
135    }
136
137    fn into_channel(self) -> Result<::fidl::AsyncChannel, Self> {
138        self.client.into_channel().map_err(|client| Self { client })
139    }
140
141    fn as_channel(&self) -> &::fidl::AsyncChannel {
142        self.client.as_channel()
143    }
144}
145
146impl LogProxy {
147    /// Create a new Proxy for fuchsia.net.stack/Log.
148    pub fn new(channel: ::fidl::AsyncChannel) -> Self {
149        let protocol_name = <LogMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
150        Self { client: fidl::client::Client::new(channel, protocol_name) }
151    }
152
153    /// Get a Stream of events from the remote end of the protocol.
154    ///
155    /// # Panics
156    ///
157    /// Panics if the event stream was already taken.
158    pub fn take_event_stream(&self) -> LogEventStream {
159        LogEventStream { event_receiver: self.client.take_event_receiver() }
160    }
161
162    /// Dynamically set packet logging.
163    pub fn r#set_log_packets(
164        &self,
165        mut enabled: bool,
166    ) -> fidl::client::QueryResponseFut<(), fidl::encoding::DefaultFuchsiaResourceDialect> {
167        LogProxyInterface::r#set_log_packets(self, enabled)
168    }
169}
170
171impl LogProxyInterface for LogProxy {
172    type SetLogPacketsResponseFut =
173        fidl::client::QueryResponseFut<(), fidl::encoding::DefaultFuchsiaResourceDialect>;
174    fn r#set_log_packets(&self, mut enabled: bool) -> Self::SetLogPacketsResponseFut {
175        fn _decode(
176            mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
177        ) -> Result<(), fidl::Error> {
178            let _response = fidl::client::decode_transaction_body::<
179                fidl::encoding::EmptyPayload,
180                fidl::encoding::DefaultFuchsiaResourceDialect,
181                0x2176044cba5f378e,
182            >(_buf?)?;
183            Ok(_response)
184        }
185        self.client.send_query_and_decode::<LogSetLogPacketsRequest, ()>(
186            (enabled,),
187            0x2176044cba5f378e,
188            fidl::encoding::DynamicFlags::empty(),
189            _decode,
190        )
191    }
192}
193
194pub struct LogEventStream {
195    event_receiver: fidl::client::EventReceiver<fidl::encoding::DefaultFuchsiaResourceDialect>,
196}
197
198impl std::marker::Unpin for LogEventStream {}
199
200impl futures::stream::FusedStream for LogEventStream {
201    fn is_terminated(&self) -> bool {
202        self.event_receiver.is_terminated()
203    }
204}
205
206impl futures::Stream for LogEventStream {
207    type Item = Result<LogEvent, fidl::Error>;
208
209    fn poll_next(
210        mut self: std::pin::Pin<&mut Self>,
211        cx: &mut std::task::Context<'_>,
212    ) -> std::task::Poll<Option<Self::Item>> {
213        match futures::ready!(futures::stream::StreamExt::poll_next_unpin(
214            &mut self.event_receiver,
215            cx
216        )?) {
217            Some(buf) => std::task::Poll::Ready(Some(LogEvent::decode(buf))),
218            None => std::task::Poll::Ready(None),
219        }
220    }
221}
222
223#[derive(Debug)]
224pub enum LogEvent {}
225
226impl LogEvent {
227    /// Decodes a message buffer as a [`LogEvent`].
228    fn decode(
229        mut buf: <fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc,
230    ) -> Result<LogEvent, fidl::Error> {
231        let (bytes, _handles) = buf.split_mut();
232        let (tx_header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
233        debug_assert_eq!(tx_header.tx_id, 0);
234        match tx_header.ordinal {
235            _ => Err(fidl::Error::UnknownOrdinal {
236                ordinal: tx_header.ordinal,
237                protocol_name: <LogMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
238            }),
239        }
240    }
241}
242
243/// A Stream of incoming requests for fuchsia.net.stack/Log.
244pub struct LogRequestStream {
245    inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
246    is_terminated: bool,
247}
248
249impl std::marker::Unpin for LogRequestStream {}
250
251impl futures::stream::FusedStream for LogRequestStream {
252    fn is_terminated(&self) -> bool {
253        self.is_terminated
254    }
255}
256
257impl fidl::endpoints::RequestStream for LogRequestStream {
258    type Protocol = LogMarker;
259    type ControlHandle = LogControlHandle;
260
261    fn from_channel(channel: ::fidl::AsyncChannel) -> Self {
262        Self { inner: std::sync::Arc::new(fidl::ServeInner::new(channel)), is_terminated: false }
263    }
264
265    fn control_handle(&self) -> Self::ControlHandle {
266        LogControlHandle { inner: self.inner.clone() }
267    }
268
269    fn into_inner(
270        self,
271    ) -> (::std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>, bool)
272    {
273        (self.inner, self.is_terminated)
274    }
275
276    fn from_inner(
277        inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
278        is_terminated: bool,
279    ) -> Self {
280        Self { inner, is_terminated }
281    }
282}
283
284impl futures::Stream for LogRequestStream {
285    type Item = Result<LogRequest, fidl::Error>;
286
287    fn poll_next(
288        mut self: std::pin::Pin<&mut Self>,
289        cx: &mut std::task::Context<'_>,
290    ) -> std::task::Poll<Option<Self::Item>> {
291        let this = &mut *self;
292        if this.inner.check_shutdown(cx) {
293            this.is_terminated = true;
294            return std::task::Poll::Ready(None);
295        }
296        if this.is_terminated {
297            panic!("polled LogRequestStream after completion");
298        }
299        fidl::encoding::with_tls_decode_buf::<_, fidl::encoding::DefaultFuchsiaResourceDialect>(
300            |bytes, handles| {
301                match this.inner.channel().read_etc(cx, bytes, handles) {
302                    std::task::Poll::Ready(Ok(())) => {}
303                    std::task::Poll::Pending => return std::task::Poll::Pending,
304                    std::task::Poll::Ready(Err(zx_status::Status::PEER_CLOSED)) => {
305                        this.is_terminated = true;
306                        return std::task::Poll::Ready(None);
307                    }
308                    std::task::Poll::Ready(Err(e)) => {
309                        return std::task::Poll::Ready(Some(Err(fidl::Error::ServerRequestRead(
310                            e.into(),
311                        ))))
312                    }
313                }
314
315                // A message has been received from the channel
316                let (header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
317
318                std::task::Poll::Ready(Some(match header.ordinal {
319                    0x2176044cba5f378e => {
320                        header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
321                        let mut req = fidl::new_empty!(
322                            LogSetLogPacketsRequest,
323                            fidl::encoding::DefaultFuchsiaResourceDialect
324                        );
325                        fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<LogSetLogPacketsRequest>(&header, _body_bytes, handles, &mut req)?;
326                        let control_handle = LogControlHandle { inner: this.inner.clone() };
327                        Ok(LogRequest::SetLogPackets {
328                            enabled: req.enabled,
329
330                            responder: LogSetLogPacketsResponder {
331                                control_handle: std::mem::ManuallyDrop::new(control_handle),
332                                tx_id: header.tx_id,
333                            },
334                        })
335                    }
336                    _ => Err(fidl::Error::UnknownOrdinal {
337                        ordinal: header.ordinal,
338                        protocol_name: <LogMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
339                    }),
340                }))
341            },
342        )
343    }
344}
345
346#[derive(Debug)]
347pub enum LogRequest {
348    /// Dynamically set packet logging.
349    SetLogPackets { enabled: bool, responder: LogSetLogPacketsResponder },
350}
351
352impl LogRequest {
353    #[allow(irrefutable_let_patterns)]
354    pub fn into_set_log_packets(self) -> Option<(bool, LogSetLogPacketsResponder)> {
355        if let LogRequest::SetLogPackets { enabled, responder } = self {
356            Some((enabled, responder))
357        } else {
358            None
359        }
360    }
361
362    /// Name of the method defined in FIDL
363    pub fn method_name(&self) -> &'static str {
364        match *self {
365            LogRequest::SetLogPackets { .. } => "set_log_packets",
366        }
367    }
368}
369
370#[derive(Debug, Clone)]
371pub struct LogControlHandle {
372    inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
373}
374
375impl fidl::endpoints::ControlHandle for LogControlHandle {
376    fn shutdown(&self) {
377        self.inner.shutdown()
378    }
379    fn shutdown_with_epitaph(&self, status: zx_status::Status) {
380        self.inner.shutdown_with_epitaph(status)
381    }
382
383    fn is_closed(&self) -> bool {
384        self.inner.channel().is_closed()
385    }
386    fn on_closed(&self) -> fidl::OnSignalsRef<'_> {
387        self.inner.channel().on_closed()
388    }
389
390    #[cfg(target_os = "fuchsia")]
391    fn signal_peer(
392        &self,
393        clear_mask: zx::Signals,
394        set_mask: zx::Signals,
395    ) -> Result<(), zx_status::Status> {
396        use fidl::Peered;
397        self.inner.channel().signal_peer(clear_mask, set_mask)
398    }
399}
400
401impl LogControlHandle {}
402
403#[must_use = "FIDL methods require a response to be sent"]
404#[derive(Debug)]
405pub struct LogSetLogPacketsResponder {
406    control_handle: std::mem::ManuallyDrop<LogControlHandle>,
407    tx_id: u32,
408}
409
410/// Set the the channel to be shutdown (see [`LogControlHandle::shutdown`])
411/// if the responder is dropped without sending a response, so that the client
412/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
413impl std::ops::Drop for LogSetLogPacketsResponder {
414    fn drop(&mut self) {
415        self.control_handle.shutdown();
416        // Safety: drops once, never accessed again
417        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
418    }
419}
420
421impl fidl::endpoints::Responder for LogSetLogPacketsResponder {
422    type ControlHandle = LogControlHandle;
423
424    fn control_handle(&self) -> &LogControlHandle {
425        &self.control_handle
426    }
427
428    fn drop_without_shutdown(mut self) {
429        // Safety: drops once, never accessed again due to mem::forget
430        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
431        // Prevent Drop from running (which would shut down the channel)
432        std::mem::forget(self);
433    }
434}
435
436impl LogSetLogPacketsResponder {
437    /// Sends a response to the FIDL transaction.
438    ///
439    /// Sets the channel to shutdown if an error occurs.
440    pub fn send(self) -> Result<(), fidl::Error> {
441        let _result = self.send_raw();
442        if _result.is_err() {
443            self.control_handle.shutdown();
444        }
445        self.drop_without_shutdown();
446        _result
447    }
448
449    /// Similar to "send" but does not shutdown the channel if an error occurs.
450    pub fn send_no_shutdown_on_err(self) -> Result<(), fidl::Error> {
451        let _result = self.send_raw();
452        self.drop_without_shutdown();
453        _result
454    }
455
456    fn send_raw(&self) -> Result<(), fidl::Error> {
457        self.control_handle.inner.send::<fidl::encoding::EmptyPayload>(
458            (),
459            self.tx_id,
460            0x2176044cba5f378e,
461            fidl::encoding::DynamicFlags::empty(),
462        )
463    }
464}
465
466#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
467pub struct StackMarker;
468
469impl fidl::endpoints::ProtocolMarker for StackMarker {
470    type Proxy = StackProxy;
471    type RequestStream = StackRequestStream;
472    #[cfg(target_os = "fuchsia")]
473    type SynchronousProxy = StackSynchronousProxy;
474
475    const DEBUG_NAME: &'static str = "fuchsia.net.stack.Stack";
476}
477impl fidl::endpoints::DiscoverableProtocolMarker for StackMarker {}
478pub type StackAddForwardingEntryResult = Result<(), Error>;
479pub type StackDelForwardingEntryResult = Result<(), Error>;
480pub type StackSetDhcpClientEnabledResult = Result<(), Error>;
481
482pub trait StackProxyInterface: Send + Sync {
483    type AddForwardingEntryResponseFut: std::future::Future<Output = Result<StackAddForwardingEntryResult, fidl::Error>>
484        + Send;
485    fn r#add_forwarding_entry(
486        &self,
487        entry: &ForwardingEntry,
488    ) -> Self::AddForwardingEntryResponseFut;
489    type DelForwardingEntryResponseFut: std::future::Future<Output = Result<StackDelForwardingEntryResult, fidl::Error>>
490        + Send;
491    fn r#del_forwarding_entry(
492        &self,
493        entry: &ForwardingEntry,
494    ) -> Self::DelForwardingEntryResponseFut;
495    type SetDhcpClientEnabledResponseFut: std::future::Future<Output = Result<StackSetDhcpClientEnabledResult, fidl::Error>>
496        + Send;
497    fn r#set_dhcp_client_enabled(
498        &self,
499        id: u64,
500        enable: bool,
501    ) -> Self::SetDhcpClientEnabledResponseFut;
502    fn r#bridge_interfaces(
503        &self,
504        interfaces: &[u64],
505        bridge: fidl::endpoints::ServerEnd<fidl_fuchsia_net_interfaces_admin::ControlMarker>,
506    ) -> Result<(), fidl::Error>;
507}
508#[derive(Debug)]
509#[cfg(target_os = "fuchsia")]
510pub struct StackSynchronousProxy {
511    client: fidl::client::sync::Client,
512}
513
514#[cfg(target_os = "fuchsia")]
515impl fidl::endpoints::SynchronousProxy for StackSynchronousProxy {
516    type Proxy = StackProxy;
517    type Protocol = StackMarker;
518
519    fn from_channel(inner: fidl::Channel) -> Self {
520        Self::new(inner)
521    }
522
523    fn into_channel(self) -> fidl::Channel {
524        self.client.into_channel()
525    }
526
527    fn as_channel(&self) -> &fidl::Channel {
528        self.client.as_channel()
529    }
530}
531
532#[cfg(target_os = "fuchsia")]
533impl StackSynchronousProxy {
534    pub fn new(channel: fidl::Channel) -> Self {
535        let protocol_name = <StackMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
536        Self { client: fidl::client::sync::Client::new(channel, protocol_name) }
537    }
538
539    pub fn into_channel(self) -> fidl::Channel {
540        self.client.into_channel()
541    }
542
543    /// Waits until an event arrives and returns it. It is safe for other
544    /// threads to make concurrent requests while waiting for an event.
545    pub fn wait_for_event(
546        &self,
547        deadline: zx::MonotonicInstant,
548    ) -> Result<StackEvent, fidl::Error> {
549        StackEvent::decode(self.client.wait_for_event(deadline)?)
550    }
551
552    /// Add a new entry to the forwarding table.
553    ///
554    /// If the table already contains an entry with the same subnet and
555    /// destination, an already exists error is returned.
556    pub fn r#add_forwarding_entry(
557        &self,
558        mut entry: &ForwardingEntry,
559        ___deadline: zx::MonotonicInstant,
560    ) -> Result<StackAddForwardingEntryResult, fidl::Error> {
561        let _response = self.client.send_query::<
562            StackAddForwardingEntryRequest,
563            fidl::encoding::ResultType<fidl::encoding::EmptyStruct, Error>,
564        >(
565            (entry,),
566            0x5fe2020877107909,
567            fidl::encoding::DynamicFlags::empty(),
568            ___deadline,
569        )?;
570        Ok(_response.map(|x| x))
571    }
572
573    /// Removes the forwarding entry. The entry must exactly match an entry in
574    /// the forwarding table, with the exception of the metric value, which is
575    /// ignored.
576    pub fn r#del_forwarding_entry(
577        &self,
578        mut entry: &ForwardingEntry,
579        ___deadline: zx::MonotonicInstant,
580    ) -> Result<StackDelForwardingEntryResult, fidl::Error> {
581        let _response = self.client.send_query::<
582            StackDelForwardingEntryRequest,
583            fidl::encoding::ResultType<fidl::encoding::EmptyStruct, Error>,
584        >(
585            (entry,),
586            0x560f3944c4cb51bd,
587            fidl::encoding::DynamicFlags::empty(),
588            ___deadline,
589        )?;
590        Ok(_response.map(|x| x))
591    }
592
593    /// Enables or disables the DHCP client on an interface.
594    /// TODO(https://fxbug.dev/42162065): Remove this once the DHCP client is moved
595    /// out of the netstack.
596    pub fn r#set_dhcp_client_enabled(
597        &self,
598        mut id: u64,
599        mut enable: bool,
600        ___deadline: zx::MonotonicInstant,
601    ) -> Result<StackSetDhcpClientEnabledResult, fidl::Error> {
602        let _response = self.client.send_query::<
603            StackSetDhcpClientEnabledRequest,
604            fidl::encoding::ResultType<fidl::encoding::EmptyStruct, Error>,
605        >(
606            (id, enable,),
607            0x6dead3a6025b0543,
608            fidl::encoding::DynamicFlags::empty(),
609            ___deadline,
610        )?;
611        Ok(_response.map(|x| x))
612    }
613
614    /// Creates a bridge over the provided `interfaces`.
615    ///
616    /// If the bridge can't be created, `bridge` is closed with a `BAD_PORT`
617    /// termination reason.
618    ///
619    /// NOTE: We're shoehorning bridging into the `admin/Control` API and
620    /// reassigning meaning to `BAD_PORT` because we don't want to leak
621    /// bridging-specific errors there. The POR is that bridging is going to get
622    /// its own API at some point.
623    ///
624    /// Bridge lifetime is controlled through the `bridge` handle.
625    pub fn r#bridge_interfaces(
626        &self,
627        mut interfaces: &[u64],
628        mut bridge: fidl::endpoints::ServerEnd<fidl_fuchsia_net_interfaces_admin::ControlMarker>,
629    ) -> Result<(), fidl::Error> {
630        self.client.send::<StackBridgeInterfacesRequest>(
631            (interfaces, bridge),
632            0x60509044a41ac976,
633            fidl::encoding::DynamicFlags::empty(),
634        )
635    }
636}
637
638#[cfg(target_os = "fuchsia")]
639impl From<StackSynchronousProxy> for zx::Handle {
640    fn from(value: StackSynchronousProxy) -> Self {
641        value.into_channel().into()
642    }
643}
644
645#[cfg(target_os = "fuchsia")]
646impl From<fidl::Channel> for StackSynchronousProxy {
647    fn from(value: fidl::Channel) -> Self {
648        Self::new(value)
649    }
650}
651
652#[derive(Debug, Clone)]
653pub struct StackProxy {
654    client: fidl::client::Client<fidl::encoding::DefaultFuchsiaResourceDialect>,
655}
656
657impl fidl::endpoints::Proxy for StackProxy {
658    type Protocol = StackMarker;
659
660    fn from_channel(inner: ::fidl::AsyncChannel) -> Self {
661        Self::new(inner)
662    }
663
664    fn into_channel(self) -> Result<::fidl::AsyncChannel, Self> {
665        self.client.into_channel().map_err(|client| Self { client })
666    }
667
668    fn as_channel(&self) -> &::fidl::AsyncChannel {
669        self.client.as_channel()
670    }
671}
672
673impl StackProxy {
674    /// Create a new Proxy for fuchsia.net.stack/Stack.
675    pub fn new(channel: ::fidl::AsyncChannel) -> Self {
676        let protocol_name = <StackMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
677        Self { client: fidl::client::Client::new(channel, protocol_name) }
678    }
679
680    /// Get a Stream of events from the remote end of the protocol.
681    ///
682    /// # Panics
683    ///
684    /// Panics if the event stream was already taken.
685    pub fn take_event_stream(&self) -> StackEventStream {
686        StackEventStream { event_receiver: self.client.take_event_receiver() }
687    }
688
689    /// Add a new entry to the forwarding table.
690    ///
691    /// If the table already contains an entry with the same subnet and
692    /// destination, an already exists error is returned.
693    pub fn r#add_forwarding_entry(
694        &self,
695        mut entry: &ForwardingEntry,
696    ) -> fidl::client::QueryResponseFut<
697        StackAddForwardingEntryResult,
698        fidl::encoding::DefaultFuchsiaResourceDialect,
699    > {
700        StackProxyInterface::r#add_forwarding_entry(self, entry)
701    }
702
703    /// Removes the forwarding entry. The entry must exactly match an entry in
704    /// the forwarding table, with the exception of the metric value, which is
705    /// ignored.
706    pub fn r#del_forwarding_entry(
707        &self,
708        mut entry: &ForwardingEntry,
709    ) -> fidl::client::QueryResponseFut<
710        StackDelForwardingEntryResult,
711        fidl::encoding::DefaultFuchsiaResourceDialect,
712    > {
713        StackProxyInterface::r#del_forwarding_entry(self, entry)
714    }
715
716    /// Enables or disables the DHCP client on an interface.
717    /// TODO(https://fxbug.dev/42162065): Remove this once the DHCP client is moved
718    /// out of the netstack.
719    pub fn r#set_dhcp_client_enabled(
720        &self,
721        mut id: u64,
722        mut enable: bool,
723    ) -> fidl::client::QueryResponseFut<
724        StackSetDhcpClientEnabledResult,
725        fidl::encoding::DefaultFuchsiaResourceDialect,
726    > {
727        StackProxyInterface::r#set_dhcp_client_enabled(self, id, enable)
728    }
729
730    /// Creates a bridge over the provided `interfaces`.
731    ///
732    /// If the bridge can't be created, `bridge` is closed with a `BAD_PORT`
733    /// termination reason.
734    ///
735    /// NOTE: We're shoehorning bridging into the `admin/Control` API and
736    /// reassigning meaning to `BAD_PORT` because we don't want to leak
737    /// bridging-specific errors there. The POR is that bridging is going to get
738    /// its own API at some point.
739    ///
740    /// Bridge lifetime is controlled through the `bridge` handle.
741    pub fn r#bridge_interfaces(
742        &self,
743        mut interfaces: &[u64],
744        mut bridge: fidl::endpoints::ServerEnd<fidl_fuchsia_net_interfaces_admin::ControlMarker>,
745    ) -> Result<(), fidl::Error> {
746        StackProxyInterface::r#bridge_interfaces(self, interfaces, bridge)
747    }
748}
749
750impl StackProxyInterface for StackProxy {
751    type AddForwardingEntryResponseFut = fidl::client::QueryResponseFut<
752        StackAddForwardingEntryResult,
753        fidl::encoding::DefaultFuchsiaResourceDialect,
754    >;
755    fn r#add_forwarding_entry(
756        &self,
757        mut entry: &ForwardingEntry,
758    ) -> Self::AddForwardingEntryResponseFut {
759        fn _decode(
760            mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
761        ) -> Result<StackAddForwardingEntryResult, fidl::Error> {
762            let _response = fidl::client::decode_transaction_body::<
763                fidl::encoding::ResultType<fidl::encoding::EmptyStruct, Error>,
764                fidl::encoding::DefaultFuchsiaResourceDialect,
765                0x5fe2020877107909,
766            >(_buf?)?;
767            Ok(_response.map(|x| x))
768        }
769        self.client
770            .send_query_and_decode::<StackAddForwardingEntryRequest, StackAddForwardingEntryResult>(
771                (entry,),
772                0x5fe2020877107909,
773                fidl::encoding::DynamicFlags::empty(),
774                _decode,
775            )
776    }
777
778    type DelForwardingEntryResponseFut = fidl::client::QueryResponseFut<
779        StackDelForwardingEntryResult,
780        fidl::encoding::DefaultFuchsiaResourceDialect,
781    >;
782    fn r#del_forwarding_entry(
783        &self,
784        mut entry: &ForwardingEntry,
785    ) -> Self::DelForwardingEntryResponseFut {
786        fn _decode(
787            mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
788        ) -> Result<StackDelForwardingEntryResult, fidl::Error> {
789            let _response = fidl::client::decode_transaction_body::<
790                fidl::encoding::ResultType<fidl::encoding::EmptyStruct, Error>,
791                fidl::encoding::DefaultFuchsiaResourceDialect,
792                0x560f3944c4cb51bd,
793            >(_buf?)?;
794            Ok(_response.map(|x| x))
795        }
796        self.client
797            .send_query_and_decode::<StackDelForwardingEntryRequest, StackDelForwardingEntryResult>(
798                (entry,),
799                0x560f3944c4cb51bd,
800                fidl::encoding::DynamicFlags::empty(),
801                _decode,
802            )
803    }
804
805    type SetDhcpClientEnabledResponseFut = fidl::client::QueryResponseFut<
806        StackSetDhcpClientEnabledResult,
807        fidl::encoding::DefaultFuchsiaResourceDialect,
808    >;
809    fn r#set_dhcp_client_enabled(
810        &self,
811        mut id: u64,
812        mut enable: bool,
813    ) -> Self::SetDhcpClientEnabledResponseFut {
814        fn _decode(
815            mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
816        ) -> Result<StackSetDhcpClientEnabledResult, fidl::Error> {
817            let _response = fidl::client::decode_transaction_body::<
818                fidl::encoding::ResultType<fidl::encoding::EmptyStruct, Error>,
819                fidl::encoding::DefaultFuchsiaResourceDialect,
820                0x6dead3a6025b0543,
821            >(_buf?)?;
822            Ok(_response.map(|x| x))
823        }
824        self.client.send_query_and_decode::<
825            StackSetDhcpClientEnabledRequest,
826            StackSetDhcpClientEnabledResult,
827        >(
828            (id, enable,),
829            0x6dead3a6025b0543,
830            fidl::encoding::DynamicFlags::empty(),
831            _decode,
832        )
833    }
834
835    fn r#bridge_interfaces(
836        &self,
837        mut interfaces: &[u64],
838        mut bridge: fidl::endpoints::ServerEnd<fidl_fuchsia_net_interfaces_admin::ControlMarker>,
839    ) -> Result<(), fidl::Error> {
840        self.client.send::<StackBridgeInterfacesRequest>(
841            (interfaces, bridge),
842            0x60509044a41ac976,
843            fidl::encoding::DynamicFlags::empty(),
844        )
845    }
846}
847
848pub struct StackEventStream {
849    event_receiver: fidl::client::EventReceiver<fidl::encoding::DefaultFuchsiaResourceDialect>,
850}
851
852impl std::marker::Unpin for StackEventStream {}
853
854impl futures::stream::FusedStream for StackEventStream {
855    fn is_terminated(&self) -> bool {
856        self.event_receiver.is_terminated()
857    }
858}
859
860impl futures::Stream for StackEventStream {
861    type Item = Result<StackEvent, fidl::Error>;
862
863    fn poll_next(
864        mut self: std::pin::Pin<&mut Self>,
865        cx: &mut std::task::Context<'_>,
866    ) -> std::task::Poll<Option<Self::Item>> {
867        match futures::ready!(futures::stream::StreamExt::poll_next_unpin(
868            &mut self.event_receiver,
869            cx
870        )?) {
871            Some(buf) => std::task::Poll::Ready(Some(StackEvent::decode(buf))),
872            None => std::task::Poll::Ready(None),
873        }
874    }
875}
876
877#[derive(Debug)]
878pub enum StackEvent {}
879
880impl StackEvent {
881    /// Decodes a message buffer as a [`StackEvent`].
882    fn decode(
883        mut buf: <fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc,
884    ) -> Result<StackEvent, fidl::Error> {
885        let (bytes, _handles) = buf.split_mut();
886        let (tx_header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
887        debug_assert_eq!(tx_header.tx_id, 0);
888        match tx_header.ordinal {
889            _ => Err(fidl::Error::UnknownOrdinal {
890                ordinal: tx_header.ordinal,
891                protocol_name: <StackMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
892            }),
893        }
894    }
895}
896
897/// A Stream of incoming requests for fuchsia.net.stack/Stack.
898pub struct StackRequestStream {
899    inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
900    is_terminated: bool,
901}
902
903impl std::marker::Unpin for StackRequestStream {}
904
905impl futures::stream::FusedStream for StackRequestStream {
906    fn is_terminated(&self) -> bool {
907        self.is_terminated
908    }
909}
910
911impl fidl::endpoints::RequestStream for StackRequestStream {
912    type Protocol = StackMarker;
913    type ControlHandle = StackControlHandle;
914
915    fn from_channel(channel: ::fidl::AsyncChannel) -> Self {
916        Self { inner: std::sync::Arc::new(fidl::ServeInner::new(channel)), is_terminated: false }
917    }
918
919    fn control_handle(&self) -> Self::ControlHandle {
920        StackControlHandle { inner: self.inner.clone() }
921    }
922
923    fn into_inner(
924        self,
925    ) -> (::std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>, bool)
926    {
927        (self.inner, self.is_terminated)
928    }
929
930    fn from_inner(
931        inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
932        is_terminated: bool,
933    ) -> Self {
934        Self { inner, is_terminated }
935    }
936}
937
938impl futures::Stream for StackRequestStream {
939    type Item = Result<StackRequest, fidl::Error>;
940
941    fn poll_next(
942        mut self: std::pin::Pin<&mut Self>,
943        cx: &mut std::task::Context<'_>,
944    ) -> std::task::Poll<Option<Self::Item>> {
945        let this = &mut *self;
946        if this.inner.check_shutdown(cx) {
947            this.is_terminated = true;
948            return std::task::Poll::Ready(None);
949        }
950        if this.is_terminated {
951            panic!("polled StackRequestStream after completion");
952        }
953        fidl::encoding::with_tls_decode_buf::<_, fidl::encoding::DefaultFuchsiaResourceDialect>(
954            |bytes, handles| {
955                match this.inner.channel().read_etc(cx, bytes, handles) {
956                    std::task::Poll::Ready(Ok(())) => {}
957                    std::task::Poll::Pending => return std::task::Poll::Pending,
958                    std::task::Poll::Ready(Err(zx_status::Status::PEER_CLOSED)) => {
959                        this.is_terminated = true;
960                        return std::task::Poll::Ready(None);
961                    }
962                    std::task::Poll::Ready(Err(e)) => {
963                        return std::task::Poll::Ready(Some(Err(fidl::Error::ServerRequestRead(
964                            e.into(),
965                        ))))
966                    }
967                }
968
969                // A message has been received from the channel
970                let (header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
971
972                std::task::Poll::Ready(Some(match header.ordinal {
973                    0x5fe2020877107909 => {
974                        header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
975                        let mut req = fidl::new_empty!(
976                            StackAddForwardingEntryRequest,
977                            fidl::encoding::DefaultFuchsiaResourceDialect
978                        );
979                        fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<StackAddForwardingEntryRequest>(&header, _body_bytes, handles, &mut req)?;
980                        let control_handle = StackControlHandle { inner: this.inner.clone() };
981                        Ok(StackRequest::AddForwardingEntry {
982                            entry: req.entry,
983
984                            responder: StackAddForwardingEntryResponder {
985                                control_handle: std::mem::ManuallyDrop::new(control_handle),
986                                tx_id: header.tx_id,
987                            },
988                        })
989                    }
990                    0x560f3944c4cb51bd => {
991                        header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
992                        let mut req = fidl::new_empty!(
993                            StackDelForwardingEntryRequest,
994                            fidl::encoding::DefaultFuchsiaResourceDialect
995                        );
996                        fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<StackDelForwardingEntryRequest>(&header, _body_bytes, handles, &mut req)?;
997                        let control_handle = StackControlHandle { inner: this.inner.clone() };
998                        Ok(StackRequest::DelForwardingEntry {
999                            entry: req.entry,
1000
1001                            responder: StackDelForwardingEntryResponder {
1002                                control_handle: std::mem::ManuallyDrop::new(control_handle),
1003                                tx_id: header.tx_id,
1004                            },
1005                        })
1006                    }
1007                    0x6dead3a6025b0543 => {
1008                        header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
1009                        let mut req = fidl::new_empty!(
1010                            StackSetDhcpClientEnabledRequest,
1011                            fidl::encoding::DefaultFuchsiaResourceDialect
1012                        );
1013                        fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<StackSetDhcpClientEnabledRequest>(&header, _body_bytes, handles, &mut req)?;
1014                        let control_handle = StackControlHandle { inner: this.inner.clone() };
1015                        Ok(StackRequest::SetDhcpClientEnabled {
1016                            id: req.id,
1017                            enable: req.enable,
1018
1019                            responder: StackSetDhcpClientEnabledResponder {
1020                                control_handle: std::mem::ManuallyDrop::new(control_handle),
1021                                tx_id: header.tx_id,
1022                            },
1023                        })
1024                    }
1025                    0x60509044a41ac976 => {
1026                        header.validate_request_tx_id(fidl::MethodType::OneWay)?;
1027                        let mut req = fidl::new_empty!(
1028                            StackBridgeInterfacesRequest,
1029                            fidl::encoding::DefaultFuchsiaResourceDialect
1030                        );
1031                        fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<StackBridgeInterfacesRequest>(&header, _body_bytes, handles, &mut req)?;
1032                        let control_handle = StackControlHandle { inner: this.inner.clone() };
1033                        Ok(StackRequest::BridgeInterfaces {
1034                            interfaces: req.interfaces,
1035                            bridge: req.bridge,
1036
1037                            control_handle,
1038                        })
1039                    }
1040                    _ => Err(fidl::Error::UnknownOrdinal {
1041                        ordinal: header.ordinal,
1042                        protocol_name: <StackMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
1043                    }),
1044                }))
1045            },
1046        )
1047    }
1048}
1049
1050#[derive(Debug)]
1051pub enum StackRequest {
1052    /// Add a new entry to the forwarding table.
1053    ///
1054    /// If the table already contains an entry with the same subnet and
1055    /// destination, an already exists error is returned.
1056    AddForwardingEntry { entry: ForwardingEntry, responder: StackAddForwardingEntryResponder },
1057    /// Removes the forwarding entry. The entry must exactly match an entry in
1058    /// the forwarding table, with the exception of the metric value, which is
1059    /// ignored.
1060    DelForwardingEntry { entry: ForwardingEntry, responder: StackDelForwardingEntryResponder },
1061    /// Enables or disables the DHCP client on an interface.
1062    /// TODO(https://fxbug.dev/42162065): Remove this once the DHCP client is moved
1063    /// out of the netstack.
1064    SetDhcpClientEnabled { id: u64, enable: bool, responder: StackSetDhcpClientEnabledResponder },
1065    /// Creates a bridge over the provided `interfaces`.
1066    ///
1067    /// If the bridge can't be created, `bridge` is closed with a `BAD_PORT`
1068    /// termination reason.
1069    ///
1070    /// NOTE: We're shoehorning bridging into the `admin/Control` API and
1071    /// reassigning meaning to `BAD_PORT` because we don't want to leak
1072    /// bridging-specific errors there. The POR is that bridging is going to get
1073    /// its own API at some point.
1074    ///
1075    /// Bridge lifetime is controlled through the `bridge` handle.
1076    BridgeInterfaces {
1077        interfaces: Vec<u64>,
1078        bridge: fidl::endpoints::ServerEnd<fidl_fuchsia_net_interfaces_admin::ControlMarker>,
1079        control_handle: StackControlHandle,
1080    },
1081}
1082
1083impl StackRequest {
1084    #[allow(irrefutable_let_patterns)]
1085    pub fn into_add_forwarding_entry(
1086        self,
1087    ) -> Option<(ForwardingEntry, StackAddForwardingEntryResponder)> {
1088        if let StackRequest::AddForwardingEntry { entry, responder } = self {
1089            Some((entry, responder))
1090        } else {
1091            None
1092        }
1093    }
1094
1095    #[allow(irrefutable_let_patterns)]
1096    pub fn into_del_forwarding_entry(
1097        self,
1098    ) -> Option<(ForwardingEntry, StackDelForwardingEntryResponder)> {
1099        if let StackRequest::DelForwardingEntry { entry, responder } = self {
1100            Some((entry, responder))
1101        } else {
1102            None
1103        }
1104    }
1105
1106    #[allow(irrefutable_let_patterns)]
1107    pub fn into_set_dhcp_client_enabled(
1108        self,
1109    ) -> Option<(u64, bool, StackSetDhcpClientEnabledResponder)> {
1110        if let StackRequest::SetDhcpClientEnabled { id, enable, responder } = self {
1111            Some((id, enable, responder))
1112        } else {
1113            None
1114        }
1115    }
1116
1117    #[allow(irrefutable_let_patterns)]
1118    pub fn into_bridge_interfaces(
1119        self,
1120    ) -> Option<(
1121        Vec<u64>,
1122        fidl::endpoints::ServerEnd<fidl_fuchsia_net_interfaces_admin::ControlMarker>,
1123        StackControlHandle,
1124    )> {
1125        if let StackRequest::BridgeInterfaces { interfaces, bridge, control_handle } = self {
1126            Some((interfaces, bridge, control_handle))
1127        } else {
1128            None
1129        }
1130    }
1131
1132    /// Name of the method defined in FIDL
1133    pub fn method_name(&self) -> &'static str {
1134        match *self {
1135            StackRequest::AddForwardingEntry { .. } => "add_forwarding_entry",
1136            StackRequest::DelForwardingEntry { .. } => "del_forwarding_entry",
1137            StackRequest::SetDhcpClientEnabled { .. } => "set_dhcp_client_enabled",
1138            StackRequest::BridgeInterfaces { .. } => "bridge_interfaces",
1139        }
1140    }
1141}
1142
1143#[derive(Debug, Clone)]
1144pub struct StackControlHandle {
1145    inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
1146}
1147
1148impl fidl::endpoints::ControlHandle for StackControlHandle {
1149    fn shutdown(&self) {
1150        self.inner.shutdown()
1151    }
1152    fn shutdown_with_epitaph(&self, status: zx_status::Status) {
1153        self.inner.shutdown_with_epitaph(status)
1154    }
1155
1156    fn is_closed(&self) -> bool {
1157        self.inner.channel().is_closed()
1158    }
1159    fn on_closed(&self) -> fidl::OnSignalsRef<'_> {
1160        self.inner.channel().on_closed()
1161    }
1162
1163    #[cfg(target_os = "fuchsia")]
1164    fn signal_peer(
1165        &self,
1166        clear_mask: zx::Signals,
1167        set_mask: zx::Signals,
1168    ) -> Result<(), zx_status::Status> {
1169        use fidl::Peered;
1170        self.inner.channel().signal_peer(clear_mask, set_mask)
1171    }
1172}
1173
1174impl StackControlHandle {}
1175
1176#[must_use = "FIDL methods require a response to be sent"]
1177#[derive(Debug)]
1178pub struct StackAddForwardingEntryResponder {
1179    control_handle: std::mem::ManuallyDrop<StackControlHandle>,
1180    tx_id: u32,
1181}
1182
1183/// Set the the channel to be shutdown (see [`StackControlHandle::shutdown`])
1184/// if the responder is dropped without sending a response, so that the client
1185/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
1186impl std::ops::Drop for StackAddForwardingEntryResponder {
1187    fn drop(&mut self) {
1188        self.control_handle.shutdown();
1189        // Safety: drops once, never accessed again
1190        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
1191    }
1192}
1193
1194impl fidl::endpoints::Responder for StackAddForwardingEntryResponder {
1195    type ControlHandle = StackControlHandle;
1196
1197    fn control_handle(&self) -> &StackControlHandle {
1198        &self.control_handle
1199    }
1200
1201    fn drop_without_shutdown(mut self) {
1202        // Safety: drops once, never accessed again due to mem::forget
1203        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
1204        // Prevent Drop from running (which would shut down the channel)
1205        std::mem::forget(self);
1206    }
1207}
1208
1209impl StackAddForwardingEntryResponder {
1210    /// Sends a response to the FIDL transaction.
1211    ///
1212    /// Sets the channel to shutdown if an error occurs.
1213    pub fn send(self, mut result: Result<(), Error>) -> Result<(), fidl::Error> {
1214        let _result = self.send_raw(result);
1215        if _result.is_err() {
1216            self.control_handle.shutdown();
1217        }
1218        self.drop_without_shutdown();
1219        _result
1220    }
1221
1222    /// Similar to "send" but does not shutdown the channel if an error occurs.
1223    pub fn send_no_shutdown_on_err(self, mut result: Result<(), Error>) -> Result<(), fidl::Error> {
1224        let _result = self.send_raw(result);
1225        self.drop_without_shutdown();
1226        _result
1227    }
1228
1229    fn send_raw(&self, mut result: Result<(), Error>) -> Result<(), fidl::Error> {
1230        self.control_handle
1231            .inner
1232            .send::<fidl::encoding::ResultType<fidl::encoding::EmptyStruct, Error>>(
1233                result,
1234                self.tx_id,
1235                0x5fe2020877107909,
1236                fidl::encoding::DynamicFlags::empty(),
1237            )
1238    }
1239}
1240
1241#[must_use = "FIDL methods require a response to be sent"]
1242#[derive(Debug)]
1243pub struct StackDelForwardingEntryResponder {
1244    control_handle: std::mem::ManuallyDrop<StackControlHandle>,
1245    tx_id: u32,
1246}
1247
1248/// Set the the channel to be shutdown (see [`StackControlHandle::shutdown`])
1249/// if the responder is dropped without sending a response, so that the client
1250/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
1251impl std::ops::Drop for StackDelForwardingEntryResponder {
1252    fn drop(&mut self) {
1253        self.control_handle.shutdown();
1254        // Safety: drops once, never accessed again
1255        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
1256    }
1257}
1258
1259impl fidl::endpoints::Responder for StackDelForwardingEntryResponder {
1260    type ControlHandle = StackControlHandle;
1261
1262    fn control_handle(&self) -> &StackControlHandle {
1263        &self.control_handle
1264    }
1265
1266    fn drop_without_shutdown(mut self) {
1267        // Safety: drops once, never accessed again due to mem::forget
1268        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
1269        // Prevent Drop from running (which would shut down the channel)
1270        std::mem::forget(self);
1271    }
1272}
1273
1274impl StackDelForwardingEntryResponder {
1275    /// Sends a response to the FIDL transaction.
1276    ///
1277    /// Sets the channel to shutdown if an error occurs.
1278    pub fn send(self, mut result: Result<(), Error>) -> Result<(), fidl::Error> {
1279        let _result = self.send_raw(result);
1280        if _result.is_err() {
1281            self.control_handle.shutdown();
1282        }
1283        self.drop_without_shutdown();
1284        _result
1285    }
1286
1287    /// Similar to "send" but does not shutdown the channel if an error occurs.
1288    pub fn send_no_shutdown_on_err(self, mut result: Result<(), Error>) -> Result<(), fidl::Error> {
1289        let _result = self.send_raw(result);
1290        self.drop_without_shutdown();
1291        _result
1292    }
1293
1294    fn send_raw(&self, mut result: Result<(), Error>) -> Result<(), fidl::Error> {
1295        self.control_handle
1296            .inner
1297            .send::<fidl::encoding::ResultType<fidl::encoding::EmptyStruct, Error>>(
1298                result,
1299                self.tx_id,
1300                0x560f3944c4cb51bd,
1301                fidl::encoding::DynamicFlags::empty(),
1302            )
1303    }
1304}
1305
1306#[must_use = "FIDL methods require a response to be sent"]
1307#[derive(Debug)]
1308pub struct StackSetDhcpClientEnabledResponder {
1309    control_handle: std::mem::ManuallyDrop<StackControlHandle>,
1310    tx_id: u32,
1311}
1312
1313/// Set the the channel to be shutdown (see [`StackControlHandle::shutdown`])
1314/// if the responder is dropped without sending a response, so that the client
1315/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
1316impl std::ops::Drop for StackSetDhcpClientEnabledResponder {
1317    fn drop(&mut self) {
1318        self.control_handle.shutdown();
1319        // Safety: drops once, never accessed again
1320        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
1321    }
1322}
1323
1324impl fidl::endpoints::Responder for StackSetDhcpClientEnabledResponder {
1325    type ControlHandle = StackControlHandle;
1326
1327    fn control_handle(&self) -> &StackControlHandle {
1328        &self.control_handle
1329    }
1330
1331    fn drop_without_shutdown(mut self) {
1332        // Safety: drops once, never accessed again due to mem::forget
1333        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
1334        // Prevent Drop from running (which would shut down the channel)
1335        std::mem::forget(self);
1336    }
1337}
1338
1339impl StackSetDhcpClientEnabledResponder {
1340    /// Sends a response to the FIDL transaction.
1341    ///
1342    /// Sets the channel to shutdown if an error occurs.
1343    pub fn send(self, mut result: Result<(), Error>) -> Result<(), fidl::Error> {
1344        let _result = self.send_raw(result);
1345        if _result.is_err() {
1346            self.control_handle.shutdown();
1347        }
1348        self.drop_without_shutdown();
1349        _result
1350    }
1351
1352    /// Similar to "send" but does not shutdown the channel if an error occurs.
1353    pub fn send_no_shutdown_on_err(self, mut result: Result<(), Error>) -> Result<(), fidl::Error> {
1354        let _result = self.send_raw(result);
1355        self.drop_without_shutdown();
1356        _result
1357    }
1358
1359    fn send_raw(&self, mut result: Result<(), Error>) -> Result<(), fidl::Error> {
1360        self.control_handle
1361            .inner
1362            .send::<fidl::encoding::ResultType<fidl::encoding::EmptyStruct, Error>>(
1363                result,
1364                self.tx_id,
1365                0x6dead3a6025b0543,
1366                fidl::encoding::DynamicFlags::empty(),
1367            )
1368    }
1369}
1370
1371mod internal {
1372    use super::*;
1373
1374    impl fidl::encoding::ResourceTypeMarker for StackBridgeInterfacesRequest {
1375        type Borrowed<'a> = &'a mut Self;
1376        fn take_or_borrow<'a>(
1377            value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
1378        ) -> Self::Borrowed<'a> {
1379            value
1380        }
1381    }
1382
1383    unsafe impl fidl::encoding::TypeMarker for StackBridgeInterfacesRequest {
1384        type Owned = Self;
1385
1386        #[inline(always)]
1387        fn inline_align(_context: fidl::encoding::Context) -> usize {
1388            8
1389        }
1390
1391        #[inline(always)]
1392        fn inline_size(_context: fidl::encoding::Context) -> usize {
1393            24
1394        }
1395    }
1396
1397    unsafe impl
1398        fidl::encoding::Encode<
1399            StackBridgeInterfacesRequest,
1400            fidl::encoding::DefaultFuchsiaResourceDialect,
1401        > for &mut StackBridgeInterfacesRequest
1402    {
1403        #[inline]
1404        unsafe fn encode(
1405            self,
1406            encoder: &mut fidl::encoding::Encoder<
1407                '_,
1408                fidl::encoding::DefaultFuchsiaResourceDialect,
1409            >,
1410            offset: usize,
1411            _depth: fidl::encoding::Depth,
1412        ) -> fidl::Result<()> {
1413            encoder.debug_check_bounds::<StackBridgeInterfacesRequest>(offset);
1414            // Delegate to tuple encoding.
1415            fidl::encoding::Encode::<StackBridgeInterfacesRequest, fidl::encoding::DefaultFuchsiaResourceDialect>::encode(
1416                (
1417                    <fidl::encoding::UnboundedVector<u64> as fidl::encoding::ValueTypeMarker>::borrow(&self.interfaces),
1418                    <fidl::encoding::Endpoint<fidl::endpoints::ServerEnd<fidl_fuchsia_net_interfaces_admin::ControlMarker>> as fidl::encoding::ResourceTypeMarker>::take_or_borrow(&mut self.bridge),
1419                ),
1420                encoder, offset, _depth
1421            )
1422        }
1423    }
1424    unsafe impl<
1425            T0: fidl::encoding::Encode<
1426                fidl::encoding::UnboundedVector<u64>,
1427                fidl::encoding::DefaultFuchsiaResourceDialect,
1428            >,
1429            T1: fidl::encoding::Encode<
1430                fidl::encoding::Endpoint<
1431                    fidl::endpoints::ServerEnd<fidl_fuchsia_net_interfaces_admin::ControlMarker>,
1432                >,
1433                fidl::encoding::DefaultFuchsiaResourceDialect,
1434            >,
1435        >
1436        fidl::encoding::Encode<
1437            StackBridgeInterfacesRequest,
1438            fidl::encoding::DefaultFuchsiaResourceDialect,
1439        > for (T0, T1)
1440    {
1441        #[inline]
1442        unsafe fn encode(
1443            self,
1444            encoder: &mut fidl::encoding::Encoder<
1445                '_,
1446                fidl::encoding::DefaultFuchsiaResourceDialect,
1447            >,
1448            offset: usize,
1449            depth: fidl::encoding::Depth,
1450        ) -> fidl::Result<()> {
1451            encoder.debug_check_bounds::<StackBridgeInterfacesRequest>(offset);
1452            // Zero out padding regions. There's no need to apply masks
1453            // because the unmasked parts will be overwritten by fields.
1454            unsafe {
1455                let ptr = encoder.buf.as_mut_ptr().add(offset).offset(16);
1456                (ptr as *mut u64).write_unaligned(0);
1457            }
1458            // Write the fields.
1459            self.0.encode(encoder, offset + 0, depth)?;
1460            self.1.encode(encoder, offset + 16, depth)?;
1461            Ok(())
1462        }
1463    }
1464
1465    impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
1466        for StackBridgeInterfacesRequest
1467    {
1468        #[inline(always)]
1469        fn new_empty() -> Self {
1470            Self {
1471                interfaces: fidl::new_empty!(
1472                    fidl::encoding::UnboundedVector<u64>,
1473                    fidl::encoding::DefaultFuchsiaResourceDialect
1474                ),
1475                bridge: fidl::new_empty!(
1476                    fidl::encoding::Endpoint<
1477                        fidl::endpoints::ServerEnd<
1478                            fidl_fuchsia_net_interfaces_admin::ControlMarker,
1479                        >,
1480                    >,
1481                    fidl::encoding::DefaultFuchsiaResourceDialect
1482                ),
1483            }
1484        }
1485
1486        #[inline]
1487        unsafe fn decode(
1488            &mut self,
1489            decoder: &mut fidl::encoding::Decoder<
1490                '_,
1491                fidl::encoding::DefaultFuchsiaResourceDialect,
1492            >,
1493            offset: usize,
1494            _depth: fidl::encoding::Depth,
1495        ) -> fidl::Result<()> {
1496            decoder.debug_check_bounds::<Self>(offset);
1497            // Verify that padding bytes are zero.
1498            let ptr = unsafe { decoder.buf.as_ptr().add(offset).offset(16) };
1499            let padval = unsafe { (ptr as *const u64).read_unaligned() };
1500            let mask = 0xffffffff00000000u64;
1501            let maskedval = padval & mask;
1502            if maskedval != 0 {
1503                return Err(fidl::Error::NonZeroPadding {
1504                    padding_start: offset + 16 + ((mask as u64).trailing_zeros() / 8) as usize,
1505                });
1506            }
1507            fidl::decode!(
1508                fidl::encoding::UnboundedVector<u64>,
1509                fidl::encoding::DefaultFuchsiaResourceDialect,
1510                &mut self.interfaces,
1511                decoder,
1512                offset + 0,
1513                _depth
1514            )?;
1515            fidl::decode!(
1516                fidl::encoding::Endpoint<
1517                    fidl::endpoints::ServerEnd<fidl_fuchsia_net_interfaces_admin::ControlMarker>,
1518                >,
1519                fidl::encoding::DefaultFuchsiaResourceDialect,
1520                &mut self.bridge,
1521                decoder,
1522                offset + 16,
1523                _depth
1524            )?;
1525            Ok(())
1526        }
1527    }
1528
1529    impl fidl::encoding::ResourceTypeMarker for StackSetDhcpClientEnabledRequest {
1530        type Borrowed<'a> = &'a mut Self;
1531        fn take_or_borrow<'a>(
1532            value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
1533        ) -> Self::Borrowed<'a> {
1534            value
1535        }
1536    }
1537
1538    unsafe impl fidl::encoding::TypeMarker for StackSetDhcpClientEnabledRequest {
1539        type Owned = Self;
1540
1541        #[inline(always)]
1542        fn inline_align(_context: fidl::encoding::Context) -> usize {
1543            8
1544        }
1545
1546        #[inline(always)]
1547        fn inline_size(_context: fidl::encoding::Context) -> usize {
1548            16
1549        }
1550    }
1551
1552    unsafe impl
1553        fidl::encoding::Encode<
1554            StackSetDhcpClientEnabledRequest,
1555            fidl::encoding::DefaultFuchsiaResourceDialect,
1556        > for &mut StackSetDhcpClientEnabledRequest
1557    {
1558        #[inline]
1559        unsafe fn encode(
1560            self,
1561            encoder: &mut fidl::encoding::Encoder<
1562                '_,
1563                fidl::encoding::DefaultFuchsiaResourceDialect,
1564            >,
1565            offset: usize,
1566            _depth: fidl::encoding::Depth,
1567        ) -> fidl::Result<()> {
1568            encoder.debug_check_bounds::<StackSetDhcpClientEnabledRequest>(offset);
1569            // Delegate to tuple encoding.
1570            fidl::encoding::Encode::<
1571                StackSetDhcpClientEnabledRequest,
1572                fidl::encoding::DefaultFuchsiaResourceDialect,
1573            >::encode(
1574                (
1575                    <u64 as fidl::encoding::ValueTypeMarker>::borrow(&self.id),
1576                    <bool as fidl::encoding::ValueTypeMarker>::borrow(&self.enable),
1577                ),
1578                encoder,
1579                offset,
1580                _depth,
1581            )
1582        }
1583    }
1584    unsafe impl<
1585            T0: fidl::encoding::Encode<u64, fidl::encoding::DefaultFuchsiaResourceDialect>,
1586            T1: fidl::encoding::Encode<bool, fidl::encoding::DefaultFuchsiaResourceDialect>,
1587        >
1588        fidl::encoding::Encode<
1589            StackSetDhcpClientEnabledRequest,
1590            fidl::encoding::DefaultFuchsiaResourceDialect,
1591        > for (T0, T1)
1592    {
1593        #[inline]
1594        unsafe fn encode(
1595            self,
1596            encoder: &mut fidl::encoding::Encoder<
1597                '_,
1598                fidl::encoding::DefaultFuchsiaResourceDialect,
1599            >,
1600            offset: usize,
1601            depth: fidl::encoding::Depth,
1602        ) -> fidl::Result<()> {
1603            encoder.debug_check_bounds::<StackSetDhcpClientEnabledRequest>(offset);
1604            // Zero out padding regions. There's no need to apply masks
1605            // because the unmasked parts will be overwritten by fields.
1606            unsafe {
1607                let ptr = encoder.buf.as_mut_ptr().add(offset).offset(8);
1608                (ptr as *mut u64).write_unaligned(0);
1609            }
1610            // Write the fields.
1611            self.0.encode(encoder, offset + 0, depth)?;
1612            self.1.encode(encoder, offset + 8, depth)?;
1613            Ok(())
1614        }
1615    }
1616
1617    impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
1618        for StackSetDhcpClientEnabledRequest
1619    {
1620        #[inline(always)]
1621        fn new_empty() -> Self {
1622            Self {
1623                id: fidl::new_empty!(u64, fidl::encoding::DefaultFuchsiaResourceDialect),
1624                enable: fidl::new_empty!(bool, fidl::encoding::DefaultFuchsiaResourceDialect),
1625            }
1626        }
1627
1628        #[inline]
1629        unsafe fn decode(
1630            &mut self,
1631            decoder: &mut fidl::encoding::Decoder<
1632                '_,
1633                fidl::encoding::DefaultFuchsiaResourceDialect,
1634            >,
1635            offset: usize,
1636            _depth: fidl::encoding::Depth,
1637        ) -> fidl::Result<()> {
1638            decoder.debug_check_bounds::<Self>(offset);
1639            // Verify that padding bytes are zero.
1640            let ptr = unsafe { decoder.buf.as_ptr().add(offset).offset(8) };
1641            let padval = unsafe { (ptr as *const u64).read_unaligned() };
1642            let mask = 0xffffffffffffff00u64;
1643            let maskedval = padval & mask;
1644            if maskedval != 0 {
1645                return Err(fidl::Error::NonZeroPadding {
1646                    padding_start: offset + 8 + ((mask as u64).trailing_zeros() / 8) as usize,
1647                });
1648            }
1649            fidl::decode!(
1650                u64,
1651                fidl::encoding::DefaultFuchsiaResourceDialect,
1652                &mut self.id,
1653                decoder,
1654                offset + 0,
1655                _depth
1656            )?;
1657            fidl::decode!(
1658                bool,
1659                fidl::encoding::DefaultFuchsiaResourceDialect,
1660                &mut self.enable,
1661                decoder,
1662                offset + 8,
1663                _depth
1664            )?;
1665            Ok(())
1666        }
1667    }
1668}