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