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