Skip to main content

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