Skip to main content

fidl_next_codec/wire/fuchsia/
status.rs

1// Copyright 2026 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use core::fmt;
6use core::mem::MaybeUninit;
7
8use munge::munge;
9
10use crate::{
11    Constrained, Decode, DecodeError, Encode, EncodeError, FromWire, FromWireRef, IntoNatural,
12    Slot, ValidationError, Wire, wire,
13};
14
15/// The wire type for [`zx::Status`].
16#[derive(Clone, Copy)]
17#[repr(transparent)]
18pub struct Status {
19    inner: wire::Int32,
20}
21
22impl Constrained for Status {
23    type Constraint = ();
24
25    fn validate(_: Slot<'_, Self>, _: Self::Constraint) -> Result<(), ValidationError> {
26        Ok(())
27    }
28}
29
30// SAFETY:
31// - Lifetime erasure: `Status` has no lifetimes, so `Narrowed` is `Self`.
32// - Padding: `Status` is transparent over `Int32`, which has no padding.
33unsafe impl Wire for Status {
34    type Narrowed<'de> = Self;
35
36    #[inline]
37    fn zero_padding(out: &mut MaybeUninit<Self>) {
38        munge!(let Self { inner } = out);
39        wire::Int32::zero_padding(inner);
40    }
41}
42
43impl Status {
44    /// Returns a `Status` with the same value as this wire type.
45    pub fn to_status(self) -> zx::Status {
46        zx::Status::from_raw(*self.inner)
47    }
48}
49
50impl From<zx::Status> for Status {
51    fn from(value: zx::Status) -> Self {
52        Self { inner: wire::Int32(value.into_raw()) }
53    }
54}
55
56impl fmt::Debug for Status {
57    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
58        self.to_status().fmt(f)
59    }
60}
61
62// SAFETY: `decode` delegates to `Int32::decode`, which initializes the underlying `Int32`
63// and ensures `slot` contains a valid decoded `Status`.
64unsafe impl<D: ?Sized> Decode<D> for Status {
65    fn decode(
66        slot: Slot<'_, Self>,
67        decoder: &mut D,
68        _: Self::Constraint,
69    ) -> Result<(), DecodeError> {
70        munge!(let Self { inner } = slot);
71        wire::Int32::decode(inner, decoder, ())
72    }
73}
74
75// SAFETY: `encode` delegates to the `Encode` implementation of the raw `i32` status value,
76// which initializes all non-padding bytes of `out`.
77unsafe impl<E: ?Sized> Encode<Status, E> for zx::Status {
78    fn encode(
79        self,
80        encoder: &mut E,
81        out: &mut MaybeUninit<Status>,
82        constraint: (),
83    ) -> Result<(), EncodeError> {
84        munge!(let Status { inner } = out);
85        self.into_raw().encode(encoder, inner, constraint)
86    }
87}
88
89// SAFETY: `encode` delegates to `zx::Status`'s `Encode` implementation, which initializes
90// all non-padding bytes of `out`.
91unsafe impl<E: ?Sized> Encode<Status, E> for &zx::Status {
92    fn encode(
93        self,
94        encoder: &mut E,
95        out: &mut MaybeUninit<Status>,
96        constraint: (),
97    ) -> Result<(), EncodeError> {
98        Encode::encode(*self, encoder, out, constraint)
99    }
100}
101
102impl FromWire<Status> for zx::Status {
103    fn from_wire(wire: Status) -> Self {
104        Self::from_wire_ref(&wire)
105    }
106}
107
108impl FromWireRef<Status> for zx::Status {
109    fn from_wire_ref(wire: &Status) -> Self {
110        Self::from_raw(*wire.inner)
111    }
112}
113
114impl IntoNatural for Status {
115    type Natural = zx::Status;
116}