Skip to main content

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