Skip to main content

fidl_fuchsia_power_powercap/
fidl_fuchsia_power_powercap.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_power_powercap_common::*;
11use futures::future::{self, MaybeDone, TryFutureExt};
12use zx_status;
13
14#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
15pub struct ClientMarker;
16
17impl fidl::endpoints::ProtocolMarker for ClientMarker {
18    type Proxy = ClientProxy;
19    type RequestStream = ClientRequestStream;
20    #[cfg(target_os = "fuchsia")]
21    type SynchronousProxy = ClientSynchronousProxy;
22
23    const DEBUG_NAME: &'static str = "fuchsia.power.powercap.Client";
24}
25impl fidl::endpoints::DiscoverableProtocolMarker for ClientMarker {}
26pub type ClientGetPowerLimitResult = Result<u64, PowercapError>;
27pub type ClientSetPowerLimitResult = Result<(), PowercapError>;
28pub type ClientGetPowerLimitBypassResult = Result<u64, PowercapError>;
29pub type ClientSetPowerLimitBypassResult = Result<(), PowercapError>;
30
31pub trait ClientProxyInterface: Send + Sync {
32    type GetPowercapTreeResponseFut: std::future::Future<Output = Result<Vec<PowercapNodeInfo>, fidl::Error>>
33        + Send;
34    fn r#get_powercap_tree(&self) -> Self::GetPowercapTreeResponseFut;
35    type GetPowerLimitResponseFut: std::future::Future<Output = Result<ClientGetPowerLimitResult, fidl::Error>>
36        + Send;
37    fn r#get_power_limit(&self, node_id: u64) -> Self::GetPowerLimitResponseFut;
38    type SetPowerLimitResponseFut: std::future::Future<Output = Result<ClientSetPowerLimitResult, fidl::Error>>
39        + Send;
40    fn r#set_power_limit(
41        &self,
42        node_id: u64,
43        power_limit_uw: u64,
44    ) -> Self::SetPowerLimitResponseFut;
45    type GetPowerLimitBypassResponseFut: std::future::Future<Output = Result<ClientGetPowerLimitBypassResult, fidl::Error>>
46        + Send;
47    fn r#get_power_limit_bypass(&self, node_id: u64) -> Self::GetPowerLimitBypassResponseFut;
48    type SetPowerLimitBypassResponseFut: std::future::Future<Output = Result<ClientSetPowerLimitBypassResult, fidl::Error>>
49        + Send;
50    fn r#set_power_limit_bypass(
51        &self,
52        node_id: u64,
53        bypass_time_ms: u64,
54    ) -> Self::SetPowerLimitBypassResponseFut;
55}
56#[derive(Debug)]
57#[cfg(target_os = "fuchsia")]
58pub struct ClientSynchronousProxy {
59    client: fidl::client::sync::Client,
60}
61
62#[cfg(target_os = "fuchsia")]
63impl fidl::endpoints::SynchronousProxy for ClientSynchronousProxy {
64    type Proxy = ClientProxy;
65    type Protocol = ClientMarker;
66
67    fn from_channel(inner: fidl::Channel) -> Self {
68        Self::new(inner)
69    }
70
71    fn into_channel(self) -> fidl::Channel {
72        self.client.into_channel()
73    }
74
75    fn as_channel(&self) -> &fidl::Channel {
76        self.client.as_channel()
77    }
78}
79
80#[cfg(target_os = "fuchsia")]
81impl ClientSynchronousProxy {
82    pub fn new(channel: fidl::Channel) -> Self {
83        Self { client: fidl::client::sync::Client::new(channel) }
84    }
85
86    pub fn into_channel(self) -> fidl::Channel {
87        self.client.into_channel()
88    }
89
90    /// Waits until an event arrives and returns it. It is safe for other
91    /// threads to make concurrent requests while waiting for an event.
92    pub fn wait_for_event(
93        &self,
94        deadline: zx::MonotonicInstant,
95    ) -> Result<ClientEvent, fidl::Error> {
96        ClientEvent::decode(self.client.wait_for_event::<ClientMarker>(deadline)?)
97    }
98
99    /// Retrieves the static powercap zone topology at container initialization.
100    pub fn r#get_powercap_tree(
101        &self,
102        ___deadline: zx::MonotonicInstant,
103    ) -> Result<Vec<PowercapNodeInfo>, fidl::Error> {
104        let _response = self.client.send_query::<
105            fidl::encoding::EmptyPayload,
106            fidl::encoding::FlexibleType<ClientGetPowercapTreeResponse>,
107            ClientMarker,
108        >(
109            (),
110            0x629216680eaef016,
111            fidl::encoding::DynamicFlags::FLEXIBLE,
112            ___deadline,
113        )?
114        .into_result::<ClientMarker>("get_powercap_tree")?;
115        Ok(_response.nodes)
116    }
117
118    /// Reads the current `constraint_0_power_limit_uw` for `node_id`.
119    ///
120    /// Before `SetPowerLimit` is called, returns the zone's initial unthrottled
121    /// limit (`max_power_uw`, or the highest entry in `power_levels_uw` if
122    /// `max_power_uw` is omitted, or `0` if neither is configured).
123    ///
124    /// Returns `PowercapError.INVALID_ARGUMENTS` if `node_id` is unknown or
125    /// refers to an unconstrained container zone.
126    pub fn r#get_power_limit(
127        &self,
128        mut node_id: u64,
129        ___deadline: zx::MonotonicInstant,
130    ) -> Result<ClientGetPowerLimitResult, fidl::Error> {
131        let _response = self.client.send_query::<
132            ClientGetPowerLimitRequest,
133            fidl::encoding::FlexibleResultType<ClientGetPowerLimitResponse, PowercapError>,
134            ClientMarker,
135        >(
136            (node_id,),
137            0x652faeb2501c31fd,
138            fidl::encoding::DynamicFlags::FLEXIBLE,
139            ___deadline,
140        )?
141        .into_result::<ClientMarker>("get_power_limit")?;
142        Ok(_response.map(|x| x.power_limit_uw))
143    }
144
145    /// Writes `constraint_0_power_limit_uw` for `node_id` (in microwatts).
146    ///
147    /// Returns `PowercapError.INVALID_ARGUMENTS` if `node_id` is unknown or
148    /// refers to an unconstrained container zone.
149    pub fn r#set_power_limit(
150        &self,
151        mut node_id: u64,
152        mut power_limit_uw: u64,
153        ___deadline: zx::MonotonicInstant,
154    ) -> Result<ClientSetPowerLimitResult, fidl::Error> {
155        let _response = self.client.send_query::<
156            ClientSetPowerLimitRequest,
157            fidl::encoding::FlexibleResultType<fidl::encoding::EmptyStruct, PowercapError>,
158            ClientMarker,
159        >(
160            (node_id, power_limit_uw,),
161            0x29acfe0139bd122e,
162            fidl::encoding::DynamicFlags::FLEXIBLE,
163            ___deadline,
164        )?
165        .into_result::<ClientMarker>("set_power_limit")?;
166        Ok(_response.map(|x| x))
167    }
168
169    /// Reads the remaining bypass duration in milliseconds (`power_limit_bypass_msec`).
170    /// Returns `0` if no bypass is currently active.
171    ///
172    /// Returns `PowercapError.INVALID_ARGUMENTS` if `node_id` is unknown or if
173    /// `supports_bypass` is not enabled on the target zone.
174    pub fn r#get_power_limit_bypass(
175        &self,
176        mut node_id: u64,
177        ___deadline: zx::MonotonicInstant,
178    ) -> Result<ClientGetPowerLimitBypassResult, fidl::Error> {
179        let _response =
180            self.client
181                .send_query::<ClientGetPowerLimitBypassRequest, fidl::encoding::FlexibleResultType<
182                    ClientGetPowerLimitBypassResponse,
183                    PowercapError,
184                >, ClientMarker>(
185                    (node_id,),
186                    0x35000ed7dfc72791,
187                    fidl::encoding::DynamicFlags::FLEXIBLE,
188                    ___deadline,
189                )?
190                .into_result::<ClientMarker>("get_power_limit_bypass")?;
191        Ok(_response.map(|x| x.remaining_bypass_ms))
192    }
193
194    /// Sets or clears the power limit bypass timer (`power_limit_bypass_msec`).
195    ///
196    /// A value of `0` immediately cancels any active bypass and restores the
197    /// cached thermal power limit. Setting a non-zero `bypass_time_ms` while a
198    /// bypass is already active replaces the active timer deadline with a new
199    /// deadline `bypass_time_ms` from now.
200    ///
201    /// Returns `PowercapError.INVALID_ARGUMENTS` if `node_id` is unknown or if
202    /// `supports_bypass` is not enabled on the target zone.
203    pub fn r#set_power_limit_bypass(
204        &self,
205        mut node_id: u64,
206        mut bypass_time_ms: u64,
207        ___deadline: zx::MonotonicInstant,
208    ) -> Result<ClientSetPowerLimitBypassResult, fidl::Error> {
209        let _response = self.client.send_query::<
210            ClientSetPowerLimitBypassRequest,
211            fidl::encoding::FlexibleResultType<fidl::encoding::EmptyStruct, PowercapError>,
212            ClientMarker,
213        >(
214            (node_id, bypass_time_ms,),
215            0x1e81290b489d0d91,
216            fidl::encoding::DynamicFlags::FLEXIBLE,
217            ___deadline,
218        )?
219        .into_result::<ClientMarker>("set_power_limit_bypass")?;
220        Ok(_response.map(|x| x))
221    }
222}
223
224#[cfg(target_os = "fuchsia")]
225impl From<ClientSynchronousProxy> for zx::NullableHandle {
226    fn from(value: ClientSynchronousProxy) -> Self {
227        value.into_channel().into()
228    }
229}
230
231#[cfg(target_os = "fuchsia")]
232impl From<fidl::Channel> for ClientSynchronousProxy {
233    fn from(value: fidl::Channel) -> Self {
234        Self::new(value)
235    }
236}
237
238#[cfg(target_os = "fuchsia")]
239impl fidl::endpoints::FromClient for ClientSynchronousProxy {
240    type Protocol = ClientMarker;
241
242    fn from_client(value: fidl::endpoints::ClientEnd<ClientMarker>) -> Self {
243        Self::new(value.into_channel())
244    }
245}
246
247#[derive(Debug, Clone)]
248pub struct ClientProxy {
249    client: fidl::client::Client<fidl::encoding::DefaultFuchsiaResourceDialect>,
250}
251
252impl fidl::endpoints::Proxy for ClientProxy {
253    type Protocol = ClientMarker;
254
255    fn from_channel(inner: ::fidl::AsyncChannel) -> Self {
256        Self::new(inner)
257    }
258
259    fn into_channel(self) -> Result<::fidl::AsyncChannel, Self> {
260        self.client.into_channel().map_err(|client| Self { client })
261    }
262
263    fn as_channel(&self) -> &::fidl::AsyncChannel {
264        self.client.as_channel()
265    }
266}
267
268impl ClientProxy {
269    /// Create a new Proxy for fuchsia.power.powercap/Client.
270    pub fn new(channel: ::fidl::AsyncChannel) -> Self {
271        let protocol_name = <ClientMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
272        Self { client: fidl::client::Client::new(channel, protocol_name) }
273    }
274
275    /// Get a Stream of events from the remote end of the protocol.
276    ///
277    /// # Panics
278    ///
279    /// Panics if the event stream was already taken.
280    pub fn take_event_stream(&self) -> ClientEventStream {
281        ClientEventStream { event_receiver: self.client.take_event_receiver() }
282    }
283
284    /// Retrieves the static powercap zone topology at container initialization.
285    pub fn r#get_powercap_tree(
286        &self,
287    ) -> fidl::client::QueryResponseFut<
288        Vec<PowercapNodeInfo>,
289        fidl::encoding::DefaultFuchsiaResourceDialect,
290    > {
291        ClientProxyInterface::r#get_powercap_tree(self)
292    }
293
294    /// Reads the current `constraint_0_power_limit_uw` for `node_id`.
295    ///
296    /// Before `SetPowerLimit` is called, returns the zone's initial unthrottled
297    /// limit (`max_power_uw`, or the highest entry in `power_levels_uw` if
298    /// `max_power_uw` is omitted, or `0` if neither is configured).
299    ///
300    /// Returns `PowercapError.INVALID_ARGUMENTS` if `node_id` is unknown or
301    /// refers to an unconstrained container zone.
302    pub fn r#get_power_limit(
303        &self,
304        mut node_id: u64,
305    ) -> fidl::client::QueryResponseFut<
306        ClientGetPowerLimitResult,
307        fidl::encoding::DefaultFuchsiaResourceDialect,
308    > {
309        ClientProxyInterface::r#get_power_limit(self, node_id)
310    }
311
312    /// Writes `constraint_0_power_limit_uw` for `node_id` (in microwatts).
313    ///
314    /// Returns `PowercapError.INVALID_ARGUMENTS` if `node_id` is unknown or
315    /// refers to an unconstrained container zone.
316    pub fn r#set_power_limit(
317        &self,
318        mut node_id: u64,
319        mut power_limit_uw: u64,
320    ) -> fidl::client::QueryResponseFut<
321        ClientSetPowerLimitResult,
322        fidl::encoding::DefaultFuchsiaResourceDialect,
323    > {
324        ClientProxyInterface::r#set_power_limit(self, node_id, power_limit_uw)
325    }
326
327    /// Reads the remaining bypass duration in milliseconds (`power_limit_bypass_msec`).
328    /// Returns `0` if no bypass is currently active.
329    ///
330    /// Returns `PowercapError.INVALID_ARGUMENTS` if `node_id` is unknown or if
331    /// `supports_bypass` is not enabled on the target zone.
332    pub fn r#get_power_limit_bypass(
333        &self,
334        mut node_id: u64,
335    ) -> fidl::client::QueryResponseFut<
336        ClientGetPowerLimitBypassResult,
337        fidl::encoding::DefaultFuchsiaResourceDialect,
338    > {
339        ClientProxyInterface::r#get_power_limit_bypass(self, node_id)
340    }
341
342    /// Sets or clears the power limit bypass timer (`power_limit_bypass_msec`).
343    ///
344    /// A value of `0` immediately cancels any active bypass and restores the
345    /// cached thermal power limit. Setting a non-zero `bypass_time_ms` while a
346    /// bypass is already active replaces the active timer deadline with a new
347    /// deadline `bypass_time_ms` from now.
348    ///
349    /// Returns `PowercapError.INVALID_ARGUMENTS` if `node_id` is unknown or if
350    /// `supports_bypass` is not enabled on the target zone.
351    pub fn r#set_power_limit_bypass(
352        &self,
353        mut node_id: u64,
354        mut bypass_time_ms: u64,
355    ) -> fidl::client::QueryResponseFut<
356        ClientSetPowerLimitBypassResult,
357        fidl::encoding::DefaultFuchsiaResourceDialect,
358    > {
359        ClientProxyInterface::r#set_power_limit_bypass(self, node_id, bypass_time_ms)
360    }
361}
362
363impl ClientProxyInterface for ClientProxy {
364    type GetPowercapTreeResponseFut = fidl::client::QueryResponseFut<
365        Vec<PowercapNodeInfo>,
366        fidl::encoding::DefaultFuchsiaResourceDialect,
367    >;
368    fn r#get_powercap_tree(&self) -> Self::GetPowercapTreeResponseFut {
369        fn _decode(
370            mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
371        ) -> Result<Vec<PowercapNodeInfo>, fidl::Error> {
372            let _response = fidl::client::decode_transaction_body::<
373                fidl::encoding::FlexibleType<ClientGetPowercapTreeResponse>,
374                fidl::encoding::DefaultFuchsiaResourceDialect,
375                0x629216680eaef016,
376            >(_buf?)?
377            .into_result::<ClientMarker>("get_powercap_tree")?;
378            Ok(_response.nodes)
379        }
380        self.client.send_query_and_decode::<fidl::encoding::EmptyPayload, Vec<PowercapNodeInfo>>(
381            (),
382            0x629216680eaef016,
383            fidl::encoding::DynamicFlags::FLEXIBLE,
384            _decode,
385        )
386    }
387
388    type GetPowerLimitResponseFut = fidl::client::QueryResponseFut<
389        ClientGetPowerLimitResult,
390        fidl::encoding::DefaultFuchsiaResourceDialect,
391    >;
392    fn r#get_power_limit(&self, mut node_id: u64) -> Self::GetPowerLimitResponseFut {
393        fn _decode(
394            mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
395        ) -> Result<ClientGetPowerLimitResult, fidl::Error> {
396            let _response = fidl::client::decode_transaction_body::<
397                fidl::encoding::FlexibleResultType<ClientGetPowerLimitResponse, PowercapError>,
398                fidl::encoding::DefaultFuchsiaResourceDialect,
399                0x652faeb2501c31fd,
400            >(_buf?)?
401            .into_result::<ClientMarker>("get_power_limit")?;
402            Ok(_response.map(|x| x.power_limit_uw))
403        }
404        self.client.send_query_and_decode::<ClientGetPowerLimitRequest, ClientGetPowerLimitResult>(
405            (node_id,),
406            0x652faeb2501c31fd,
407            fidl::encoding::DynamicFlags::FLEXIBLE,
408            _decode,
409        )
410    }
411
412    type SetPowerLimitResponseFut = fidl::client::QueryResponseFut<
413        ClientSetPowerLimitResult,
414        fidl::encoding::DefaultFuchsiaResourceDialect,
415    >;
416    fn r#set_power_limit(
417        &self,
418        mut node_id: u64,
419        mut power_limit_uw: u64,
420    ) -> Self::SetPowerLimitResponseFut {
421        fn _decode(
422            mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
423        ) -> Result<ClientSetPowerLimitResult, fidl::Error> {
424            let _response = fidl::client::decode_transaction_body::<
425                fidl::encoding::FlexibleResultType<fidl::encoding::EmptyStruct, PowercapError>,
426                fidl::encoding::DefaultFuchsiaResourceDialect,
427                0x29acfe0139bd122e,
428            >(_buf?)?
429            .into_result::<ClientMarker>("set_power_limit")?;
430            Ok(_response.map(|x| x))
431        }
432        self.client.send_query_and_decode::<ClientSetPowerLimitRequest, ClientSetPowerLimitResult>(
433            (node_id, power_limit_uw),
434            0x29acfe0139bd122e,
435            fidl::encoding::DynamicFlags::FLEXIBLE,
436            _decode,
437        )
438    }
439
440    type GetPowerLimitBypassResponseFut = fidl::client::QueryResponseFut<
441        ClientGetPowerLimitBypassResult,
442        fidl::encoding::DefaultFuchsiaResourceDialect,
443    >;
444    fn r#get_power_limit_bypass(&self, mut node_id: u64) -> Self::GetPowerLimitBypassResponseFut {
445        fn _decode(
446            mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
447        ) -> Result<ClientGetPowerLimitBypassResult, fidl::Error> {
448            let _response = fidl::client::decode_transaction_body::<
449                fidl::encoding::FlexibleResultType<
450                    ClientGetPowerLimitBypassResponse,
451                    PowercapError,
452                >,
453                fidl::encoding::DefaultFuchsiaResourceDialect,
454                0x35000ed7dfc72791,
455            >(_buf?)?
456            .into_result::<ClientMarker>("get_power_limit_bypass")?;
457            Ok(_response.map(|x| x.remaining_bypass_ms))
458        }
459        self.client.send_query_and_decode::<
460            ClientGetPowerLimitBypassRequest,
461            ClientGetPowerLimitBypassResult,
462        >(
463            (node_id,),
464            0x35000ed7dfc72791,
465            fidl::encoding::DynamicFlags::FLEXIBLE,
466            _decode,
467        )
468    }
469
470    type SetPowerLimitBypassResponseFut = fidl::client::QueryResponseFut<
471        ClientSetPowerLimitBypassResult,
472        fidl::encoding::DefaultFuchsiaResourceDialect,
473    >;
474    fn r#set_power_limit_bypass(
475        &self,
476        mut node_id: u64,
477        mut bypass_time_ms: u64,
478    ) -> Self::SetPowerLimitBypassResponseFut {
479        fn _decode(
480            mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
481        ) -> Result<ClientSetPowerLimitBypassResult, fidl::Error> {
482            let _response = fidl::client::decode_transaction_body::<
483                fidl::encoding::FlexibleResultType<fidl::encoding::EmptyStruct, PowercapError>,
484                fidl::encoding::DefaultFuchsiaResourceDialect,
485                0x1e81290b489d0d91,
486            >(_buf?)?
487            .into_result::<ClientMarker>("set_power_limit_bypass")?;
488            Ok(_response.map(|x| x))
489        }
490        self.client.send_query_and_decode::<
491            ClientSetPowerLimitBypassRequest,
492            ClientSetPowerLimitBypassResult,
493        >(
494            (node_id, bypass_time_ms,),
495            0x1e81290b489d0d91,
496            fidl::encoding::DynamicFlags::FLEXIBLE,
497            _decode,
498        )
499    }
500}
501
502pub struct ClientEventStream {
503    event_receiver: fidl::client::EventReceiver<fidl::encoding::DefaultFuchsiaResourceDialect>,
504}
505
506impl std::marker::Unpin for ClientEventStream {}
507
508impl futures::stream::FusedStream for ClientEventStream {
509    fn is_terminated(&self) -> bool {
510        self.event_receiver.is_terminated()
511    }
512}
513
514impl futures::Stream for ClientEventStream {
515    type Item = Result<ClientEvent, fidl::Error>;
516
517    fn poll_next(
518        mut self: std::pin::Pin<&mut Self>,
519        cx: &mut std::task::Context<'_>,
520    ) -> std::task::Poll<Option<Self::Item>> {
521        match futures::ready!(futures::stream::StreamExt::poll_next_unpin(
522            &mut self.event_receiver,
523            cx
524        )?) {
525            Some(buf) => std::task::Poll::Ready(Some(ClientEvent::decode(buf))),
526            None => std::task::Poll::Ready(None),
527        }
528    }
529}
530
531#[derive(Debug)]
532pub enum ClientEvent {
533    #[non_exhaustive]
534    _UnknownEvent {
535        /// Ordinal of the event that was sent.
536        ordinal: u64,
537    },
538}
539
540impl ClientEvent {
541    /// Decodes a message buffer as a [`ClientEvent`].
542    fn decode(
543        mut buf: <fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc,
544    ) -> Result<ClientEvent, fidl::Error> {
545        let (bytes, _handles) = buf.split_mut();
546        let (tx_header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
547        debug_assert_eq!(tx_header.tx_id, 0);
548        match tx_header.ordinal {
549            _ if tx_header.dynamic_flags().contains(fidl::encoding::DynamicFlags::FLEXIBLE) => {
550                Ok(ClientEvent::_UnknownEvent { ordinal: tx_header.ordinal })
551            }
552            _ => Err(fidl::Error::UnknownOrdinal {
553                ordinal: tx_header.ordinal,
554                protocol_name: <ClientMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
555            }),
556        }
557    }
558}
559
560/// A Stream of incoming requests for fuchsia.power.powercap/Client.
561pub struct ClientRequestStream {
562    inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
563    is_terminated: bool,
564}
565
566impl std::marker::Unpin for ClientRequestStream {}
567
568impl futures::stream::FusedStream for ClientRequestStream {
569    fn is_terminated(&self) -> bool {
570        self.is_terminated
571    }
572}
573
574impl fidl::endpoints::RequestStream for ClientRequestStream {
575    type Protocol = ClientMarker;
576    type ControlHandle = ClientControlHandle;
577
578    fn from_channel(channel: ::fidl::AsyncChannel) -> Self {
579        Self { inner: std::sync::Arc::new(fidl::ServeInner::new(channel)), is_terminated: false }
580    }
581
582    fn control_handle(&self) -> Self::ControlHandle {
583        ClientControlHandle { inner: self.inner.clone() }
584    }
585
586    fn into_inner(
587        self,
588    ) -> (::std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>, bool)
589    {
590        (self.inner, self.is_terminated)
591    }
592
593    fn from_inner(
594        inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
595        is_terminated: bool,
596    ) -> Self {
597        Self { inner, is_terminated }
598    }
599}
600
601impl futures::Stream for ClientRequestStream {
602    type Item = Result<ClientRequest, fidl::Error>;
603
604    fn poll_next(
605        mut self: std::pin::Pin<&mut Self>,
606        cx: &mut std::task::Context<'_>,
607    ) -> std::task::Poll<Option<Self::Item>> {
608        let this = &mut *self;
609        if this.inner.check_shutdown(cx) {
610            this.is_terminated = true;
611            return std::task::Poll::Ready(None);
612        }
613        if this.is_terminated {
614            panic!("polled ClientRequestStream after completion");
615        }
616        fidl::encoding::with_tls_decode_buf::<_, fidl::encoding::DefaultFuchsiaResourceDialect>(
617            |bytes, handles| {
618                match this.inner.channel().read_etc(cx, bytes, handles) {
619                    std::task::Poll::Ready(Ok(())) => {}
620                    std::task::Poll::Pending => return std::task::Poll::Pending,
621                    std::task::Poll::Ready(Err(zx_status::Status::PEER_CLOSED)) => {
622                        this.is_terminated = true;
623                        return std::task::Poll::Ready(None);
624                    }
625                    std::task::Poll::Ready(Err(e)) => {
626                        return std::task::Poll::Ready(Some(Err(fidl::Error::ServerRequestRead(
627                            e.into(),
628                        ))));
629                    }
630                }
631
632                // A message has been received from the channel
633                let (header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
634
635                std::task::Poll::Ready(Some(match header.ordinal {
636                    0x629216680eaef016 => {
637                        header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
638                        let mut req = fidl::new_empty!(
639                            fidl::encoding::EmptyPayload,
640                            fidl::encoding::DefaultFuchsiaResourceDialect
641                        );
642                        fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
643                        let control_handle = ClientControlHandle { inner: this.inner.clone() };
644                        Ok(ClientRequest::GetPowercapTree {
645                            responder: ClientGetPowercapTreeResponder {
646                                control_handle: std::mem::ManuallyDrop::new(control_handle),
647                                tx_id: header.tx_id,
648                            },
649                        })
650                    }
651                    0x652faeb2501c31fd => {
652                        header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
653                        let mut req = fidl::new_empty!(
654                            ClientGetPowerLimitRequest,
655                            fidl::encoding::DefaultFuchsiaResourceDialect
656                        );
657                        fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<ClientGetPowerLimitRequest>(&header, _body_bytes, handles, &mut req)?;
658                        let control_handle = ClientControlHandle { inner: this.inner.clone() };
659                        Ok(ClientRequest::GetPowerLimit {
660                            node_id: req.node_id,
661
662                            responder: ClientGetPowerLimitResponder {
663                                control_handle: std::mem::ManuallyDrop::new(control_handle),
664                                tx_id: header.tx_id,
665                            },
666                        })
667                    }
668                    0x29acfe0139bd122e => {
669                        header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
670                        let mut req = fidl::new_empty!(
671                            ClientSetPowerLimitRequest,
672                            fidl::encoding::DefaultFuchsiaResourceDialect
673                        );
674                        fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<ClientSetPowerLimitRequest>(&header, _body_bytes, handles, &mut req)?;
675                        let control_handle = ClientControlHandle { inner: this.inner.clone() };
676                        Ok(ClientRequest::SetPowerLimit {
677                            node_id: req.node_id,
678                            power_limit_uw: req.power_limit_uw,
679
680                            responder: ClientSetPowerLimitResponder {
681                                control_handle: std::mem::ManuallyDrop::new(control_handle),
682                                tx_id: header.tx_id,
683                            },
684                        })
685                    }
686                    0x35000ed7dfc72791 => {
687                        header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
688                        let mut req = fidl::new_empty!(
689                            ClientGetPowerLimitBypassRequest,
690                            fidl::encoding::DefaultFuchsiaResourceDialect
691                        );
692                        fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<ClientGetPowerLimitBypassRequest>(&header, _body_bytes, handles, &mut req)?;
693                        let control_handle = ClientControlHandle { inner: this.inner.clone() };
694                        Ok(ClientRequest::GetPowerLimitBypass {
695                            node_id: req.node_id,
696
697                            responder: ClientGetPowerLimitBypassResponder {
698                                control_handle: std::mem::ManuallyDrop::new(control_handle),
699                                tx_id: header.tx_id,
700                            },
701                        })
702                    }
703                    0x1e81290b489d0d91 => {
704                        header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
705                        let mut req = fidl::new_empty!(
706                            ClientSetPowerLimitBypassRequest,
707                            fidl::encoding::DefaultFuchsiaResourceDialect
708                        );
709                        fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<ClientSetPowerLimitBypassRequest>(&header, _body_bytes, handles, &mut req)?;
710                        let control_handle = ClientControlHandle { inner: this.inner.clone() };
711                        Ok(ClientRequest::SetPowerLimitBypass {
712                            node_id: req.node_id,
713                            bypass_time_ms: req.bypass_time_ms,
714
715                            responder: ClientSetPowerLimitBypassResponder {
716                                control_handle: std::mem::ManuallyDrop::new(control_handle),
717                                tx_id: header.tx_id,
718                            },
719                        })
720                    }
721                    _ if header.tx_id == 0
722                        && header
723                            .dynamic_flags()
724                            .contains(fidl::encoding::DynamicFlags::FLEXIBLE) =>
725                    {
726                        Ok(ClientRequest::_UnknownMethod {
727                            ordinal: header.ordinal,
728                            control_handle: ClientControlHandle { inner: this.inner.clone() },
729                            method_type: fidl::MethodType::OneWay,
730                        })
731                    }
732                    _ if header
733                        .dynamic_flags()
734                        .contains(fidl::encoding::DynamicFlags::FLEXIBLE) =>
735                    {
736                        this.inner.send_framework_err(
737                            fidl::encoding::FrameworkErr::UnknownMethod,
738                            header.tx_id,
739                            header.ordinal,
740                            header.dynamic_flags(),
741                            (bytes, handles),
742                        )?;
743                        Ok(ClientRequest::_UnknownMethod {
744                            ordinal: header.ordinal,
745                            control_handle: ClientControlHandle { inner: this.inner.clone() },
746                            method_type: fidl::MethodType::TwoWay,
747                        })
748                    }
749                    _ => Err(fidl::Error::UnknownOrdinal {
750                        ordinal: header.ordinal,
751                        protocol_name:
752                            <ClientMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
753                    }),
754                }))
755            },
756        )
757    }
758}
759
760/// Protocol used by Starnix to build and interact with the `/sys/class/powercap`
761/// hierarchy backed by Power Manager's `PowercapController`.
762#[derive(Debug)]
763pub enum ClientRequest {
764    /// Retrieves the static powercap zone topology at container initialization.
765    GetPowercapTree { responder: ClientGetPowercapTreeResponder },
766    /// Reads the current `constraint_0_power_limit_uw` for `node_id`.
767    ///
768    /// Before `SetPowerLimit` is called, returns the zone's initial unthrottled
769    /// limit (`max_power_uw`, or the highest entry in `power_levels_uw` if
770    /// `max_power_uw` is omitted, or `0` if neither is configured).
771    ///
772    /// Returns `PowercapError.INVALID_ARGUMENTS` if `node_id` is unknown or
773    /// refers to an unconstrained container zone.
774    GetPowerLimit { node_id: u64, responder: ClientGetPowerLimitResponder },
775    /// Writes `constraint_0_power_limit_uw` for `node_id` (in microwatts).
776    ///
777    /// Returns `PowercapError.INVALID_ARGUMENTS` if `node_id` is unknown or
778    /// refers to an unconstrained container zone.
779    SetPowerLimit { node_id: u64, power_limit_uw: u64, responder: ClientSetPowerLimitResponder },
780    /// Reads the remaining bypass duration in milliseconds (`power_limit_bypass_msec`).
781    /// Returns `0` if no bypass is currently active.
782    ///
783    /// Returns `PowercapError.INVALID_ARGUMENTS` if `node_id` is unknown or if
784    /// `supports_bypass` is not enabled on the target zone.
785    GetPowerLimitBypass { node_id: u64, responder: ClientGetPowerLimitBypassResponder },
786    /// Sets or clears the power limit bypass timer (`power_limit_bypass_msec`).
787    ///
788    /// A value of `0` immediately cancels any active bypass and restores the
789    /// cached thermal power limit. Setting a non-zero `bypass_time_ms` while a
790    /// bypass is already active replaces the active timer deadline with a new
791    /// deadline `bypass_time_ms` from now.
792    ///
793    /// Returns `PowercapError.INVALID_ARGUMENTS` if `node_id` is unknown or if
794    /// `supports_bypass` is not enabled on the target zone.
795    SetPowerLimitBypass {
796        node_id: u64,
797        bypass_time_ms: u64,
798        responder: ClientSetPowerLimitBypassResponder,
799    },
800    /// An interaction was received which does not match any known method.
801    #[non_exhaustive]
802    _UnknownMethod {
803        /// Ordinal of the method that was called.
804        ordinal: u64,
805        control_handle: ClientControlHandle,
806        method_type: fidl::MethodType,
807    },
808}
809
810impl ClientRequest {
811    #[allow(irrefutable_let_patterns)]
812    pub fn into_get_powercap_tree(self) -> Option<(ClientGetPowercapTreeResponder)> {
813        if let ClientRequest::GetPowercapTree { responder } = self {
814            Some((responder))
815        } else {
816            None
817        }
818    }
819
820    #[allow(irrefutable_let_patterns)]
821    pub fn into_get_power_limit(self) -> Option<(u64, ClientGetPowerLimitResponder)> {
822        if let ClientRequest::GetPowerLimit { node_id, responder } = self {
823            Some((node_id, responder))
824        } else {
825            None
826        }
827    }
828
829    #[allow(irrefutable_let_patterns)]
830    pub fn into_set_power_limit(self) -> Option<(u64, u64, ClientSetPowerLimitResponder)> {
831        if let ClientRequest::SetPowerLimit { node_id, power_limit_uw, responder } = self {
832            Some((node_id, power_limit_uw, responder))
833        } else {
834            None
835        }
836    }
837
838    #[allow(irrefutable_let_patterns)]
839    pub fn into_get_power_limit_bypass(self) -> Option<(u64, ClientGetPowerLimitBypassResponder)> {
840        if let ClientRequest::GetPowerLimitBypass { node_id, responder } = self {
841            Some((node_id, responder))
842        } else {
843            None
844        }
845    }
846
847    #[allow(irrefutable_let_patterns)]
848    pub fn into_set_power_limit_bypass(
849        self,
850    ) -> Option<(u64, u64, ClientSetPowerLimitBypassResponder)> {
851        if let ClientRequest::SetPowerLimitBypass { node_id, bypass_time_ms, responder } = self {
852            Some((node_id, bypass_time_ms, responder))
853        } else {
854            None
855        }
856    }
857
858    /// Name of the method defined in FIDL
859    pub fn method_name(&self) -> &'static str {
860        match *self {
861            ClientRequest::GetPowercapTree { .. } => "get_powercap_tree",
862            ClientRequest::GetPowerLimit { .. } => "get_power_limit",
863            ClientRequest::SetPowerLimit { .. } => "set_power_limit",
864            ClientRequest::GetPowerLimitBypass { .. } => "get_power_limit_bypass",
865            ClientRequest::SetPowerLimitBypass { .. } => "set_power_limit_bypass",
866            ClientRequest::_UnknownMethod { method_type: fidl::MethodType::OneWay, .. } => {
867                "unknown one-way method"
868            }
869            ClientRequest::_UnknownMethod { method_type: fidl::MethodType::TwoWay, .. } => {
870                "unknown two-way method"
871            }
872        }
873    }
874}
875
876#[derive(Debug, Clone)]
877pub struct ClientControlHandle {
878    inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
879}
880
881impl ClientControlHandle {
882    pub fn shutdown_with_epitaph(&self, status: impl Into<fidl::Epitaph>) {
883        self.inner.shutdown_with_epitaph(status.into())
884    }
885}
886
887impl fidl::endpoints::ControlHandle for ClientControlHandle {
888    fn shutdown(&self) {
889        self.inner.shutdown()
890    }
891
892    fn shutdown_with_epitaph(&self, status: fidl::Epitaph) {
893        self.inner.shutdown_with_epitaph(status)
894    }
895
896    fn is_closed(&self) -> bool {
897        self.inner.channel().is_closed()
898    }
899    fn on_closed(&self) -> fidl::OnSignalsRef<'_> {
900        self.inner.channel().on_closed()
901    }
902
903    #[cfg(target_os = "fuchsia")]
904    fn signal_peer(
905        &self,
906        clear_mask: zx::Signals,
907        set_mask: zx::Signals,
908    ) -> Result<(), zx_status::Status> {
909        use fidl::Peered;
910        self.inner.channel().signal_peer(clear_mask, set_mask)
911    }
912}
913
914impl ClientControlHandle {}
915
916#[must_use = "FIDL methods require a response to be sent"]
917#[derive(Debug)]
918pub struct ClientGetPowercapTreeResponder {
919    control_handle: std::mem::ManuallyDrop<ClientControlHandle>,
920    tx_id: u32,
921}
922
923/// Set the the channel to be shutdown (see [`ClientControlHandle::shutdown`])
924/// if the responder is dropped without sending a response, so that the client
925/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
926impl std::ops::Drop for ClientGetPowercapTreeResponder {
927    fn drop(&mut self) {
928        self.control_handle.shutdown();
929        // Safety: drops once, never accessed again
930        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
931    }
932}
933
934impl fidl::endpoints::Responder for ClientGetPowercapTreeResponder {
935    type ControlHandle = ClientControlHandle;
936
937    fn control_handle(&self) -> &ClientControlHandle {
938        &self.control_handle
939    }
940
941    fn drop_without_shutdown(mut self) {
942        // Safety: drops once, never accessed again due to mem::forget
943        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
944        // Prevent Drop from running (which would shut down the channel)
945        std::mem::forget(self);
946    }
947}
948
949impl ClientGetPowercapTreeResponder {
950    /// Sends a response to the FIDL transaction.
951    ///
952    /// Sets the channel to shutdown if an error occurs.
953    pub fn send(self, mut nodes: &[PowercapNodeInfo]) -> Result<(), fidl::Error> {
954        let _result = self.send_raw(nodes);
955        if _result.is_err() {
956            self.control_handle.shutdown();
957        }
958        self.drop_without_shutdown();
959        _result
960    }
961
962    /// Similar to "send" but does not shutdown the channel if an error occurs.
963    pub fn send_no_shutdown_on_err(
964        self,
965        mut nodes: &[PowercapNodeInfo],
966    ) -> Result<(), fidl::Error> {
967        let _result = self.send_raw(nodes);
968        self.drop_without_shutdown();
969        _result
970    }
971
972    fn send_raw(&self, mut nodes: &[PowercapNodeInfo]) -> Result<(), fidl::Error> {
973        self.control_handle
974            .inner
975            .send::<fidl::encoding::FlexibleType<ClientGetPowercapTreeResponse>>(
976                fidl::encoding::Flexible::new((nodes,)),
977                self.tx_id,
978                0x629216680eaef016,
979                fidl::encoding::DynamicFlags::FLEXIBLE,
980            )
981    }
982}
983
984#[must_use = "FIDL methods require a response to be sent"]
985#[derive(Debug)]
986pub struct ClientGetPowerLimitResponder {
987    control_handle: std::mem::ManuallyDrop<ClientControlHandle>,
988    tx_id: u32,
989}
990
991/// Set the the channel to be shutdown (see [`ClientControlHandle::shutdown`])
992/// if the responder is dropped without sending a response, so that the client
993/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
994impl std::ops::Drop for ClientGetPowerLimitResponder {
995    fn drop(&mut self) {
996        self.control_handle.shutdown();
997        // Safety: drops once, never accessed again
998        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
999    }
1000}
1001
1002impl fidl::endpoints::Responder for ClientGetPowerLimitResponder {
1003    type ControlHandle = ClientControlHandle;
1004
1005    fn control_handle(&self) -> &ClientControlHandle {
1006        &self.control_handle
1007    }
1008
1009    fn drop_without_shutdown(mut self) {
1010        // Safety: drops once, never accessed again due to mem::forget
1011        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
1012        // Prevent Drop from running (which would shut down the channel)
1013        std::mem::forget(self);
1014    }
1015}
1016
1017impl ClientGetPowerLimitResponder {
1018    /// Sends a response to the FIDL transaction.
1019    ///
1020    /// Sets the channel to shutdown if an error occurs.
1021    pub fn send(self, mut result: Result<u64, PowercapError>) -> Result<(), fidl::Error> {
1022        let _result = self.send_raw(result);
1023        if _result.is_err() {
1024            self.control_handle.shutdown();
1025        }
1026        self.drop_without_shutdown();
1027        _result
1028    }
1029
1030    /// Similar to "send" but does not shutdown the channel if an error occurs.
1031    pub fn send_no_shutdown_on_err(
1032        self,
1033        mut result: Result<u64, PowercapError>,
1034    ) -> Result<(), fidl::Error> {
1035        let _result = self.send_raw(result);
1036        self.drop_without_shutdown();
1037        _result
1038    }
1039
1040    fn send_raw(&self, mut result: Result<u64, PowercapError>) -> Result<(), fidl::Error> {
1041        self.control_handle.inner.send::<fidl::encoding::FlexibleResultType<
1042            ClientGetPowerLimitResponse,
1043            PowercapError,
1044        >>(
1045            fidl::encoding::FlexibleResult::new(result.map(|power_limit_uw| (power_limit_uw,))),
1046            self.tx_id,
1047            0x652faeb2501c31fd,
1048            fidl::encoding::DynamicFlags::FLEXIBLE,
1049        )
1050    }
1051}
1052
1053#[must_use = "FIDL methods require a response to be sent"]
1054#[derive(Debug)]
1055pub struct ClientSetPowerLimitResponder {
1056    control_handle: std::mem::ManuallyDrop<ClientControlHandle>,
1057    tx_id: u32,
1058}
1059
1060/// Set the the channel to be shutdown (see [`ClientControlHandle::shutdown`])
1061/// if the responder is dropped without sending a response, so that the client
1062/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
1063impl std::ops::Drop for ClientSetPowerLimitResponder {
1064    fn drop(&mut self) {
1065        self.control_handle.shutdown();
1066        // Safety: drops once, never accessed again
1067        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
1068    }
1069}
1070
1071impl fidl::endpoints::Responder for ClientSetPowerLimitResponder {
1072    type ControlHandle = ClientControlHandle;
1073
1074    fn control_handle(&self) -> &ClientControlHandle {
1075        &self.control_handle
1076    }
1077
1078    fn drop_without_shutdown(mut self) {
1079        // Safety: drops once, never accessed again due to mem::forget
1080        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
1081        // Prevent Drop from running (which would shut down the channel)
1082        std::mem::forget(self);
1083    }
1084}
1085
1086impl ClientSetPowerLimitResponder {
1087    /// Sends a response to the FIDL transaction.
1088    ///
1089    /// Sets the channel to shutdown if an error occurs.
1090    pub fn send(self, mut result: Result<(), PowercapError>) -> Result<(), fidl::Error> {
1091        let _result = self.send_raw(result);
1092        if _result.is_err() {
1093            self.control_handle.shutdown();
1094        }
1095        self.drop_without_shutdown();
1096        _result
1097    }
1098
1099    /// Similar to "send" but does not shutdown the channel if an error occurs.
1100    pub fn send_no_shutdown_on_err(
1101        self,
1102        mut result: Result<(), PowercapError>,
1103    ) -> Result<(), fidl::Error> {
1104        let _result = self.send_raw(result);
1105        self.drop_without_shutdown();
1106        _result
1107    }
1108
1109    fn send_raw(&self, mut result: Result<(), PowercapError>) -> Result<(), fidl::Error> {
1110        self.control_handle.inner.send::<fidl::encoding::FlexibleResultType<
1111            fidl::encoding::EmptyStruct,
1112            PowercapError,
1113        >>(
1114            fidl::encoding::FlexibleResult::new(result),
1115            self.tx_id,
1116            0x29acfe0139bd122e,
1117            fidl::encoding::DynamicFlags::FLEXIBLE,
1118        )
1119    }
1120}
1121
1122#[must_use = "FIDL methods require a response to be sent"]
1123#[derive(Debug)]
1124pub struct ClientGetPowerLimitBypassResponder {
1125    control_handle: std::mem::ManuallyDrop<ClientControlHandle>,
1126    tx_id: u32,
1127}
1128
1129/// Set the the channel to be shutdown (see [`ClientControlHandle::shutdown`])
1130/// if the responder is dropped without sending a response, so that the client
1131/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
1132impl std::ops::Drop for ClientGetPowerLimitBypassResponder {
1133    fn drop(&mut self) {
1134        self.control_handle.shutdown();
1135        // Safety: drops once, never accessed again
1136        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
1137    }
1138}
1139
1140impl fidl::endpoints::Responder for ClientGetPowerLimitBypassResponder {
1141    type ControlHandle = ClientControlHandle;
1142
1143    fn control_handle(&self) -> &ClientControlHandle {
1144        &self.control_handle
1145    }
1146
1147    fn drop_without_shutdown(mut self) {
1148        // Safety: drops once, never accessed again due to mem::forget
1149        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
1150        // Prevent Drop from running (which would shut down the channel)
1151        std::mem::forget(self);
1152    }
1153}
1154
1155impl ClientGetPowerLimitBypassResponder {
1156    /// Sends a response to the FIDL transaction.
1157    ///
1158    /// Sets the channel to shutdown if an error occurs.
1159    pub fn send(self, mut result: Result<u64, PowercapError>) -> Result<(), fidl::Error> {
1160        let _result = self.send_raw(result);
1161        if _result.is_err() {
1162            self.control_handle.shutdown();
1163        }
1164        self.drop_without_shutdown();
1165        _result
1166    }
1167
1168    /// Similar to "send" but does not shutdown the channel if an error occurs.
1169    pub fn send_no_shutdown_on_err(
1170        self,
1171        mut result: Result<u64, PowercapError>,
1172    ) -> Result<(), fidl::Error> {
1173        let _result = self.send_raw(result);
1174        self.drop_without_shutdown();
1175        _result
1176    }
1177
1178    fn send_raw(&self, mut result: Result<u64, PowercapError>) -> Result<(), fidl::Error> {
1179        self.control_handle.inner.send::<fidl::encoding::FlexibleResultType<
1180            ClientGetPowerLimitBypassResponse,
1181            PowercapError,
1182        >>(
1183            fidl::encoding::FlexibleResult::new(
1184                result.map(|remaining_bypass_ms| (remaining_bypass_ms,)),
1185            ),
1186            self.tx_id,
1187            0x35000ed7dfc72791,
1188            fidl::encoding::DynamicFlags::FLEXIBLE,
1189        )
1190    }
1191}
1192
1193#[must_use = "FIDL methods require a response to be sent"]
1194#[derive(Debug)]
1195pub struct ClientSetPowerLimitBypassResponder {
1196    control_handle: std::mem::ManuallyDrop<ClientControlHandle>,
1197    tx_id: u32,
1198}
1199
1200/// Set the the channel to be shutdown (see [`ClientControlHandle::shutdown`])
1201/// if the responder is dropped without sending a response, so that the client
1202/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
1203impl std::ops::Drop for ClientSetPowerLimitBypassResponder {
1204    fn drop(&mut self) {
1205        self.control_handle.shutdown();
1206        // Safety: drops once, never accessed again
1207        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
1208    }
1209}
1210
1211impl fidl::endpoints::Responder for ClientSetPowerLimitBypassResponder {
1212    type ControlHandle = ClientControlHandle;
1213
1214    fn control_handle(&self) -> &ClientControlHandle {
1215        &self.control_handle
1216    }
1217
1218    fn drop_without_shutdown(mut self) {
1219        // Safety: drops once, never accessed again due to mem::forget
1220        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
1221        // Prevent Drop from running (which would shut down the channel)
1222        std::mem::forget(self);
1223    }
1224}
1225
1226impl ClientSetPowerLimitBypassResponder {
1227    /// Sends a response to the FIDL transaction.
1228    ///
1229    /// Sets the channel to shutdown if an error occurs.
1230    pub fn send(self, mut result: Result<(), PowercapError>) -> Result<(), fidl::Error> {
1231        let _result = self.send_raw(result);
1232        if _result.is_err() {
1233            self.control_handle.shutdown();
1234        }
1235        self.drop_without_shutdown();
1236        _result
1237    }
1238
1239    /// Similar to "send" but does not shutdown the channel if an error occurs.
1240    pub fn send_no_shutdown_on_err(
1241        self,
1242        mut result: Result<(), PowercapError>,
1243    ) -> Result<(), fidl::Error> {
1244        let _result = self.send_raw(result);
1245        self.drop_without_shutdown();
1246        _result
1247    }
1248
1249    fn send_raw(&self, mut result: Result<(), PowercapError>) -> Result<(), fidl::Error> {
1250        self.control_handle.inner.send::<fidl::encoding::FlexibleResultType<
1251            fidl::encoding::EmptyStruct,
1252            PowercapError,
1253        >>(
1254            fidl::encoding::FlexibleResult::new(result),
1255            self.tx_id,
1256            0x1e81290b489d0d91,
1257            fidl::encoding::DynamicFlags::FLEXIBLE,
1258        )
1259    }
1260}
1261
1262#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
1263pub struct ClientStateWatcherMarker;
1264
1265impl fidl::endpoints::ProtocolMarker for ClientStateWatcherMarker {
1266    type Proxy = ClientStateWatcherProxy;
1267    type RequestStream = ClientStateWatcherRequestStream;
1268    #[cfg(target_os = "fuchsia")]
1269    type SynchronousProxy = ClientStateWatcherSynchronousProxy;
1270
1271    const DEBUG_NAME: &'static str = "fuchsia.power.powercap.ClientStateWatcher";
1272}
1273impl fidl::endpoints::DiscoverableProtocolMarker for ClientStateWatcherMarker {}
1274
1275pub trait ClientStateWatcherProxyInterface: Send + Sync {
1276    type WatchResponseFut: std::future::Future<Output = Result<Vec<u64>, fidl::Error>> + Send;
1277    fn r#watch(&self) -> Self::WatchResponseFut;
1278}
1279#[derive(Debug)]
1280#[cfg(target_os = "fuchsia")]
1281pub struct ClientStateWatcherSynchronousProxy {
1282    client: fidl::client::sync::Client,
1283}
1284
1285#[cfg(target_os = "fuchsia")]
1286impl fidl::endpoints::SynchronousProxy for ClientStateWatcherSynchronousProxy {
1287    type Proxy = ClientStateWatcherProxy;
1288    type Protocol = ClientStateWatcherMarker;
1289
1290    fn from_channel(inner: fidl::Channel) -> Self {
1291        Self::new(inner)
1292    }
1293
1294    fn into_channel(self) -> fidl::Channel {
1295        self.client.into_channel()
1296    }
1297
1298    fn as_channel(&self) -> &fidl::Channel {
1299        self.client.as_channel()
1300    }
1301}
1302
1303#[cfg(target_os = "fuchsia")]
1304impl ClientStateWatcherSynchronousProxy {
1305    pub fn new(channel: fidl::Channel) -> Self {
1306        Self { client: fidl::client::sync::Client::new(channel) }
1307    }
1308
1309    pub fn into_channel(self) -> fidl::Channel {
1310        self.client.into_channel()
1311    }
1312
1313    /// Waits until an event arrives and returns it. It is safe for other
1314    /// threads to make concurrent requests while waiting for an event.
1315    pub fn wait_for_event(
1316        &self,
1317        deadline: zx::MonotonicInstant,
1318    ) -> Result<ClientStateWatcherEvent, fidl::Error> {
1319        ClientStateWatcherEvent::decode(
1320            self.client.wait_for_event::<ClientStateWatcherMarker>(deadline)?,
1321        )
1322    }
1323
1324    /// Hanging-get that returns a vector of OPP indices indexed by `cluster_id`.
1325    ///
1326    /// Returns immediately on the first call for a connection with the current
1327    /// per-cluster OPP ceilings, and blocks on subsequent calls until `domain_opps`
1328    /// changes.
1329    ///
1330    /// OPP index `0` represents the highest-frequency (unthrottled) operating
1331    /// point, with larger indices representing lower frequency ceilings (matching
1332    /// `fuchsia.power.cpu/DomainController`).
1333    pub fn r#watch(&self, ___deadline: zx::MonotonicInstant) -> Result<Vec<u64>, fidl::Error> {
1334        let _response = self.client.send_query::<
1335            fidl::encoding::EmptyPayload,
1336            fidl::encoding::FlexibleType<ClientStateWatcherWatchResponse>,
1337            ClientStateWatcherMarker,
1338        >(
1339            (),
1340            0x2066699d14b6ee1d,
1341            fidl::encoding::DynamicFlags::FLEXIBLE,
1342            ___deadline,
1343        )?
1344        .into_result::<ClientStateWatcherMarker>("watch")?;
1345        Ok(_response.domain_opps)
1346    }
1347}
1348
1349#[cfg(target_os = "fuchsia")]
1350impl From<ClientStateWatcherSynchronousProxy> for zx::NullableHandle {
1351    fn from(value: ClientStateWatcherSynchronousProxy) -> Self {
1352        value.into_channel().into()
1353    }
1354}
1355
1356#[cfg(target_os = "fuchsia")]
1357impl From<fidl::Channel> for ClientStateWatcherSynchronousProxy {
1358    fn from(value: fidl::Channel) -> Self {
1359        Self::new(value)
1360    }
1361}
1362
1363#[cfg(target_os = "fuchsia")]
1364impl fidl::endpoints::FromClient for ClientStateWatcherSynchronousProxy {
1365    type Protocol = ClientStateWatcherMarker;
1366
1367    fn from_client(value: fidl::endpoints::ClientEnd<ClientStateWatcherMarker>) -> Self {
1368        Self::new(value.into_channel())
1369    }
1370}
1371
1372#[derive(Debug, Clone)]
1373pub struct ClientStateWatcherProxy {
1374    client: fidl::client::Client<fidl::encoding::DefaultFuchsiaResourceDialect>,
1375}
1376
1377impl fidl::endpoints::Proxy for ClientStateWatcherProxy {
1378    type Protocol = ClientStateWatcherMarker;
1379
1380    fn from_channel(inner: ::fidl::AsyncChannel) -> Self {
1381        Self::new(inner)
1382    }
1383
1384    fn into_channel(self) -> Result<::fidl::AsyncChannel, Self> {
1385        self.client.into_channel().map_err(|client| Self { client })
1386    }
1387
1388    fn as_channel(&self) -> &::fidl::AsyncChannel {
1389        self.client.as_channel()
1390    }
1391}
1392
1393impl ClientStateWatcherProxy {
1394    /// Create a new Proxy for fuchsia.power.powercap/ClientStateWatcher.
1395    pub fn new(channel: ::fidl::AsyncChannel) -> Self {
1396        let protocol_name =
1397            <ClientStateWatcherMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
1398        Self { client: fidl::client::Client::new(channel, protocol_name) }
1399    }
1400
1401    /// Get a Stream of events from the remote end of the protocol.
1402    ///
1403    /// # Panics
1404    ///
1405    /// Panics if the event stream was already taken.
1406    pub fn take_event_stream(&self) -> ClientStateWatcherEventStream {
1407        ClientStateWatcherEventStream { event_receiver: self.client.take_event_receiver() }
1408    }
1409
1410    /// Hanging-get that returns a vector of OPP indices indexed by `cluster_id`.
1411    ///
1412    /// Returns immediately on the first call for a connection with the current
1413    /// per-cluster OPP ceilings, and blocks on subsequent calls until `domain_opps`
1414    /// changes.
1415    ///
1416    /// OPP index `0` represents the highest-frequency (unthrottled) operating
1417    /// point, with larger indices representing lower frequency ceilings (matching
1418    /// `fuchsia.power.cpu/DomainController`).
1419    pub fn r#watch(
1420        &self,
1421    ) -> fidl::client::QueryResponseFut<Vec<u64>, fidl::encoding::DefaultFuchsiaResourceDialect>
1422    {
1423        ClientStateWatcherProxyInterface::r#watch(self)
1424    }
1425}
1426
1427impl ClientStateWatcherProxyInterface for ClientStateWatcherProxy {
1428    type WatchResponseFut =
1429        fidl::client::QueryResponseFut<Vec<u64>, fidl::encoding::DefaultFuchsiaResourceDialect>;
1430    fn r#watch(&self) -> Self::WatchResponseFut {
1431        fn _decode(
1432            mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
1433        ) -> Result<Vec<u64>, fidl::Error> {
1434            let _response = fidl::client::decode_transaction_body::<
1435                fidl::encoding::FlexibleType<ClientStateWatcherWatchResponse>,
1436                fidl::encoding::DefaultFuchsiaResourceDialect,
1437                0x2066699d14b6ee1d,
1438            >(_buf?)?
1439            .into_result::<ClientStateWatcherMarker>("watch")?;
1440            Ok(_response.domain_opps)
1441        }
1442        self.client.send_query_and_decode::<fidl::encoding::EmptyPayload, Vec<u64>>(
1443            (),
1444            0x2066699d14b6ee1d,
1445            fidl::encoding::DynamicFlags::FLEXIBLE,
1446            _decode,
1447        )
1448    }
1449}
1450
1451pub struct ClientStateWatcherEventStream {
1452    event_receiver: fidl::client::EventReceiver<fidl::encoding::DefaultFuchsiaResourceDialect>,
1453}
1454
1455impl std::marker::Unpin for ClientStateWatcherEventStream {}
1456
1457impl futures::stream::FusedStream for ClientStateWatcherEventStream {
1458    fn is_terminated(&self) -> bool {
1459        self.event_receiver.is_terminated()
1460    }
1461}
1462
1463impl futures::Stream for ClientStateWatcherEventStream {
1464    type Item = Result<ClientStateWatcherEvent, fidl::Error>;
1465
1466    fn poll_next(
1467        mut self: std::pin::Pin<&mut Self>,
1468        cx: &mut std::task::Context<'_>,
1469    ) -> std::task::Poll<Option<Self::Item>> {
1470        match futures::ready!(futures::stream::StreamExt::poll_next_unpin(
1471            &mut self.event_receiver,
1472            cx
1473        )?) {
1474            Some(buf) => std::task::Poll::Ready(Some(ClientStateWatcherEvent::decode(buf))),
1475            None => std::task::Poll::Ready(None),
1476        }
1477    }
1478}
1479
1480#[derive(Debug)]
1481pub enum ClientStateWatcherEvent {
1482    #[non_exhaustive]
1483    _UnknownEvent {
1484        /// Ordinal of the event that was sent.
1485        ordinal: u64,
1486    },
1487}
1488
1489impl ClientStateWatcherEvent {
1490    /// Decodes a message buffer as a [`ClientStateWatcherEvent`].
1491    fn decode(
1492        mut buf: <fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc,
1493    ) -> Result<ClientStateWatcherEvent, fidl::Error> {
1494        let (bytes, _handles) = buf.split_mut();
1495        let (tx_header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
1496        debug_assert_eq!(tx_header.tx_id, 0);
1497        match tx_header.ordinal {
1498            _ if tx_header.dynamic_flags().contains(fidl::encoding::DynamicFlags::FLEXIBLE) => {
1499                Ok(ClientStateWatcherEvent::_UnknownEvent { ordinal: tx_header.ordinal })
1500            }
1501            _ => Err(fidl::Error::UnknownOrdinal {
1502                ordinal: tx_header.ordinal,
1503                protocol_name:
1504                    <ClientStateWatcherMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
1505            }),
1506        }
1507    }
1508}
1509
1510/// A Stream of incoming requests for fuchsia.power.powercap/ClientStateWatcher.
1511pub struct ClientStateWatcherRequestStream {
1512    inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
1513    is_terminated: bool,
1514}
1515
1516impl std::marker::Unpin for ClientStateWatcherRequestStream {}
1517
1518impl futures::stream::FusedStream for ClientStateWatcherRequestStream {
1519    fn is_terminated(&self) -> bool {
1520        self.is_terminated
1521    }
1522}
1523
1524impl fidl::endpoints::RequestStream for ClientStateWatcherRequestStream {
1525    type Protocol = ClientStateWatcherMarker;
1526    type ControlHandle = ClientStateWatcherControlHandle;
1527
1528    fn from_channel(channel: ::fidl::AsyncChannel) -> Self {
1529        Self { inner: std::sync::Arc::new(fidl::ServeInner::new(channel)), is_terminated: false }
1530    }
1531
1532    fn control_handle(&self) -> Self::ControlHandle {
1533        ClientStateWatcherControlHandle { inner: self.inner.clone() }
1534    }
1535
1536    fn into_inner(
1537        self,
1538    ) -> (::std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>, bool)
1539    {
1540        (self.inner, self.is_terminated)
1541    }
1542
1543    fn from_inner(
1544        inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
1545        is_terminated: bool,
1546    ) -> Self {
1547        Self { inner, is_terminated }
1548    }
1549}
1550
1551impl futures::Stream for ClientStateWatcherRequestStream {
1552    type Item = Result<ClientStateWatcherRequest, fidl::Error>;
1553
1554    fn poll_next(
1555        mut self: std::pin::Pin<&mut Self>,
1556        cx: &mut std::task::Context<'_>,
1557    ) -> std::task::Poll<Option<Self::Item>> {
1558        let this = &mut *self;
1559        if this.inner.check_shutdown(cx) {
1560            this.is_terminated = true;
1561            return std::task::Poll::Ready(None);
1562        }
1563        if this.is_terminated {
1564            panic!("polled ClientStateWatcherRequestStream after completion");
1565        }
1566        fidl::encoding::with_tls_decode_buf::<_, fidl::encoding::DefaultFuchsiaResourceDialect>(
1567            |bytes, handles| {
1568                match this.inner.channel().read_etc(cx, bytes, handles) {
1569                    std::task::Poll::Ready(Ok(())) => {}
1570                    std::task::Poll::Pending => return std::task::Poll::Pending,
1571                    std::task::Poll::Ready(Err(zx_status::Status::PEER_CLOSED)) => {
1572                        this.is_terminated = true;
1573                        return std::task::Poll::Ready(None);
1574                    }
1575                    std::task::Poll::Ready(Err(e)) => {
1576                        return std::task::Poll::Ready(Some(Err(fidl::Error::ServerRequestRead(
1577                            e.into(),
1578                        ))));
1579                    }
1580                }
1581
1582                // A message has been received from the channel
1583                let (header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
1584
1585                std::task::Poll::Ready(Some(match header.ordinal {
1586                0x2066699d14b6ee1d => {
1587                    header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
1588                    let mut req = fidl::new_empty!(fidl::encoding::EmptyPayload, fidl::encoding::DefaultFuchsiaResourceDialect);
1589                    fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<fidl::encoding::EmptyPayload>(&header, _body_bytes, handles, &mut req)?;
1590                    let control_handle = ClientStateWatcherControlHandle {
1591                        inner: this.inner.clone(),
1592                    };
1593                    Ok(ClientStateWatcherRequest::Watch {
1594                        responder: ClientStateWatcherWatchResponder {
1595                            control_handle: std::mem::ManuallyDrop::new(control_handle),
1596                            tx_id: header.tx_id,
1597                        },
1598                    })
1599                }
1600                _ if header.tx_id == 0 && header.dynamic_flags().contains(fidl::encoding::DynamicFlags::FLEXIBLE) => {
1601                    Ok(ClientStateWatcherRequest::_UnknownMethod {
1602                        ordinal: header.ordinal,
1603                        control_handle: ClientStateWatcherControlHandle { inner: this.inner.clone() },
1604                        method_type: fidl::MethodType::OneWay,
1605                    })
1606                }
1607                _ if header.dynamic_flags().contains(fidl::encoding::DynamicFlags::FLEXIBLE) => {
1608                    this.inner.send_framework_err(
1609                        fidl::encoding::FrameworkErr::UnknownMethod,
1610                        header.tx_id,
1611                        header.ordinal,
1612                        header.dynamic_flags(),
1613                        (bytes, handles),
1614                    )?;
1615                    Ok(ClientStateWatcherRequest::_UnknownMethod {
1616                        ordinal: header.ordinal,
1617                        control_handle: ClientStateWatcherControlHandle { inner: this.inner.clone() },
1618                        method_type: fidl::MethodType::TwoWay,
1619                    })
1620                }
1621                _ => Err(fidl::Error::UnknownOrdinal {
1622                    ordinal: header.ordinal,
1623                    protocol_name: <ClientStateWatcherMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
1624                }),
1625            }))
1626            },
1627        )
1628    }
1629}
1630
1631/// Hanging-get protocol used by `cpu_manager` to observe per-cluster OPP ceiling
1632/// changes computed by `PowercapController`.
1633#[derive(Debug)]
1634pub enum ClientStateWatcherRequest {
1635    /// Hanging-get that returns a vector of OPP indices indexed by `cluster_id`.
1636    ///
1637    /// Returns immediately on the first call for a connection with the current
1638    /// per-cluster OPP ceilings, and blocks on subsequent calls until `domain_opps`
1639    /// changes.
1640    ///
1641    /// OPP index `0` represents the highest-frequency (unthrottled) operating
1642    /// point, with larger indices representing lower frequency ceilings (matching
1643    /// `fuchsia.power.cpu/DomainController`).
1644    Watch { responder: ClientStateWatcherWatchResponder },
1645    /// An interaction was received which does not match any known method.
1646    #[non_exhaustive]
1647    _UnknownMethod {
1648        /// Ordinal of the method that was called.
1649        ordinal: u64,
1650        control_handle: ClientStateWatcherControlHandle,
1651        method_type: fidl::MethodType,
1652    },
1653}
1654
1655impl ClientStateWatcherRequest {
1656    #[allow(irrefutable_let_patterns)]
1657    pub fn into_watch(self) -> Option<(ClientStateWatcherWatchResponder)> {
1658        if let ClientStateWatcherRequest::Watch { responder } = self {
1659            Some((responder))
1660        } else {
1661            None
1662        }
1663    }
1664
1665    /// Name of the method defined in FIDL
1666    pub fn method_name(&self) -> &'static str {
1667        match *self {
1668            ClientStateWatcherRequest::Watch { .. } => "watch",
1669            ClientStateWatcherRequest::_UnknownMethod {
1670                method_type: fidl::MethodType::OneWay,
1671                ..
1672            } => "unknown one-way method",
1673            ClientStateWatcherRequest::_UnknownMethod {
1674                method_type: fidl::MethodType::TwoWay,
1675                ..
1676            } => "unknown two-way method",
1677        }
1678    }
1679}
1680
1681#[derive(Debug, Clone)]
1682pub struct ClientStateWatcherControlHandle {
1683    inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
1684}
1685
1686impl ClientStateWatcherControlHandle {
1687    pub fn shutdown_with_epitaph(&self, status: impl Into<fidl::Epitaph>) {
1688        self.inner.shutdown_with_epitaph(status.into())
1689    }
1690}
1691
1692impl fidl::endpoints::ControlHandle for ClientStateWatcherControlHandle {
1693    fn shutdown(&self) {
1694        self.inner.shutdown()
1695    }
1696
1697    fn shutdown_with_epitaph(&self, status: fidl::Epitaph) {
1698        self.inner.shutdown_with_epitaph(status)
1699    }
1700
1701    fn is_closed(&self) -> bool {
1702        self.inner.channel().is_closed()
1703    }
1704    fn on_closed(&self) -> fidl::OnSignalsRef<'_> {
1705        self.inner.channel().on_closed()
1706    }
1707
1708    #[cfg(target_os = "fuchsia")]
1709    fn signal_peer(
1710        &self,
1711        clear_mask: zx::Signals,
1712        set_mask: zx::Signals,
1713    ) -> Result<(), zx_status::Status> {
1714        use fidl::Peered;
1715        self.inner.channel().signal_peer(clear_mask, set_mask)
1716    }
1717}
1718
1719impl ClientStateWatcherControlHandle {}
1720
1721#[must_use = "FIDL methods require a response to be sent"]
1722#[derive(Debug)]
1723pub struct ClientStateWatcherWatchResponder {
1724    control_handle: std::mem::ManuallyDrop<ClientStateWatcherControlHandle>,
1725    tx_id: u32,
1726}
1727
1728/// Set the the channel to be shutdown (see [`ClientStateWatcherControlHandle::shutdown`])
1729/// if the responder is dropped without sending a response, so that the client
1730/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
1731impl std::ops::Drop for ClientStateWatcherWatchResponder {
1732    fn drop(&mut self) {
1733        self.control_handle.shutdown();
1734        // Safety: drops once, never accessed again
1735        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
1736    }
1737}
1738
1739impl fidl::endpoints::Responder for ClientStateWatcherWatchResponder {
1740    type ControlHandle = ClientStateWatcherControlHandle;
1741
1742    fn control_handle(&self) -> &ClientStateWatcherControlHandle {
1743        &self.control_handle
1744    }
1745
1746    fn drop_without_shutdown(mut self) {
1747        // Safety: drops once, never accessed again due to mem::forget
1748        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
1749        // Prevent Drop from running (which would shut down the channel)
1750        std::mem::forget(self);
1751    }
1752}
1753
1754impl ClientStateWatcherWatchResponder {
1755    /// Sends a response to the FIDL transaction.
1756    ///
1757    /// Sets the channel to shutdown if an error occurs.
1758    pub fn send(self, mut domain_opps: &[u64]) -> Result<(), fidl::Error> {
1759        let _result = self.send_raw(domain_opps);
1760        if _result.is_err() {
1761            self.control_handle.shutdown();
1762        }
1763        self.drop_without_shutdown();
1764        _result
1765    }
1766
1767    /// Similar to "send" but does not shutdown the channel if an error occurs.
1768    pub fn send_no_shutdown_on_err(self, mut domain_opps: &[u64]) -> Result<(), fidl::Error> {
1769        let _result = self.send_raw(domain_opps);
1770        self.drop_without_shutdown();
1771        _result
1772    }
1773
1774    fn send_raw(&self, mut domain_opps: &[u64]) -> Result<(), fidl::Error> {
1775        self.control_handle
1776            .inner
1777            .send::<fidl::encoding::FlexibleType<ClientStateWatcherWatchResponse>>(
1778                fidl::encoding::Flexible::new((domain_opps,)),
1779                self.tx_id,
1780                0x2066699d14b6ee1d,
1781                fidl::encoding::DynamicFlags::FLEXIBLE,
1782            )
1783    }
1784}
1785
1786mod internal {
1787    use super::*;
1788}