fidl_next_codec/wire/fuchsia/
status.rs1use 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#[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
30unsafe 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 pub fn into_raw(self) -> i32 {
46 *self.inner
47 }
48
49 pub fn to_status(self) -> zx::Status {
51 zx::Status::try_from_raw(*self.inner).unwrap()
52 }
53}
54
55impl From<zx::Status> for Status {
56 fn from(value: zx::Status) -> Self {
57 Self { inner: wire::Int32(value.into_raw()) }
58 }
59}
60
61impl fmt::Debug for Status {
62 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
63 self.to_status().fmt(f)
64 }
65}
66
67unsafe impl<D: ?Sized> Decode<D> for Status {
70 fn decode(
71 slot: Slot<'_, Self>,
72 decoder: &mut D,
73 _: Self::Constraint,
74 ) -> Result<(), DecodeError> {
75 munge!(let Self { mut inner } = slot);
76 wire::Int32::decode(inner.as_mut(), decoder, ())?;
77 if *inner == 0 {
78 return Err(DecodeError::InvalidNonZeroInteger);
79 }
80 Ok(())
81 }
82}
83
84unsafe impl<E: ?Sized> Encode<Status, E> for zx::Status {
87 fn encode(
88 self,
89 encoder: &mut E,
90 out: &mut MaybeUninit<Status>,
91 constraint: (),
92 ) -> Result<(), EncodeError> {
93 munge!(let Status { inner } = out);
94 self.into_raw().encode(encoder, inner, constraint)
95 }
96}
97
98unsafe impl<E: ?Sized> Encode<Status, E> for &zx::Status {
101 fn encode(
102 self,
103 encoder: &mut E,
104 out: &mut MaybeUninit<Status>,
105 constraint: (),
106 ) -> Result<(), EncodeError> {
107 Encode::encode(*self, encoder, out, constraint)
108 }
109}
110
111impl FromWire<Status> for zx::Status {
112 fn from_wire(wire: Status) -> Self {
113 Self::from_wire_ref(&wire)
114 }
115}
116
117impl FromWireRef<Status> for zx::Status {
118 fn from_wire_ref(wire: &Status) -> Self {
119 wire.to_status()
120 }
121}
122
123impl IntoNatural for Status {
124 type Natural = zx::Status;
125}
126
127#[cfg(test)]
128mod tests {
129 use super::*;
130 use crate::CHUNK_SIZE;
131
132 #[test]
133 fn test_status_decode_zero() {
134 let mut buffer = [0u8; CHUNK_SIZE];
135 let mut slot = unsafe { Slot::<Status>::new_unchecked(buffer.as_mut_ptr().cast()) };
137 Status::decode(slot.as_mut(), &mut (), ()).expect_err("successfully decoded 0 as Status");
138 }
139
140 #[test]
141 fn test_status_decode_error() {
142 let mut buffer = [0u8; CHUNK_SIZE];
143 let status_raw = zx::Status::NOT_SUPPORTED.into_raw();
144 buffer[..4].copy_from_slice(&status_raw.to_le_bytes());
145
146 let mut slot = unsafe { Slot::<Status>::new_unchecked(buffer.as_mut_ptr().cast()) };
148 Status::decode(slot.as_mut(), &mut (), ()).expect("failed to decode error as Status");
149 let wire_result = unsafe { slot.as_ptr().cast::<Status>().read() };
151 assert_eq!(wire_result.to_status(), zx::Status::NOT_SUPPORTED);
152 assert_eq!(
153 <zx::Status as FromWire<Status>>::from_wire(wire_result),
154 zx::Status::NOT_SUPPORTED
155 );
156 }
157
158 #[test]
159 fn test_status_result_encode() {
160 let mut out = MaybeUninit::<Status>::uninit();
161 let status = zx::Status::NOT_FOUND;
162 status.encode(&mut (), &mut out, ()).unwrap();
163 let encoded = unsafe { out.assume_init() };
165 assert_eq!(encoded.into_raw(), zx::Status::NOT_FOUND.into_raw());
166 }
167}