fidl_next_codec/convert/
from.rs1use core::mem::{MaybeUninit, forget};
6use core::ptr::copy_nonoverlapping;
7
8use crate::CopyOptimization;
9
10pub trait FromWire<W>: Sized {
12 const COPY_OPTIMIZATION: CopyOptimization<W, Self> = CopyOptimization::disable();
16
17 fn from_wire(wire: W) -> Self;
19}
20
21pub trait FromWireRef<W>: FromWire<W> {
23 fn from_wire_ref(wire: &W) -> Self;
25}
26
27pub trait FromWireOption<W>: Sized {
29 fn from_wire_option(wire: W) -> Option<Self>;
31}
32
33pub trait FromWireOptionRef<W>: FromWireOption<W> {
35 fn from_wire_option_ref(wire: &W) -> Option<Self>;
37}
38
39impl<T: FromWire<W>, W, const N: usize> FromWire<[W; N]> for [T; N] {
40 fn from_wire(wire: [W; N]) -> Self {
41 let mut result = MaybeUninit::<[T; N]>::uninit();
42 if T::COPY_OPTIMIZATION.is_enabled() {
43 unsafe {
45 copy_nonoverlapping(wire.as_ptr().cast(), result.as_mut_ptr(), 1);
46 }
47 forget(wire);
48 } else {
49 for (i, item) in wire.into_iter().enumerate() {
50 unsafe {
51 result.as_mut_ptr().cast::<T>().add(i).write(T::from_wire(item));
52 }
53 }
54 }
55 unsafe { result.assume_init() }
56 }
57}
58
59impl<T: FromWireRef<W>, W, const N: usize> FromWireRef<[W; N]> for [T; N] {
60 fn from_wire_ref(wire: &[W; N]) -> Self {
61 let mut result = MaybeUninit::<[T; N]>::uninit();
62 if T::COPY_OPTIMIZATION.is_enabled() {
63 unsafe {
65 copy_nonoverlapping(wire.as_ptr().cast(), result.as_mut_ptr(), 1);
66 }
67 } else {
68 for (i, item) in wire.iter().enumerate() {
69 unsafe {
70 result.as_mut_ptr().cast::<T>().add(i).write(T::from_wire_ref(item));
71 }
72 }
73 }
74 unsafe { result.assume_init() }
75 }
76}
77
78impl<T: FromWire<W>, W> FromWire<W> for Box<T> {
79 fn from_wire(wire: W) -> Self {
80 Box::new(T::from_wire(wire))
81 }
82}
83
84impl<T: FromWireRef<W>, W> FromWireRef<W> for Box<T> {
85 fn from_wire_ref(wire: &W) -> Self {
86 Box::new(T::from_wire_ref(wire))
87 }
88}
89
90impl<T: FromWireOption<W>, W> FromWire<W> for Option<T> {
91 fn from_wire(wire: W) -> Self {
92 T::from_wire_option(wire)
93 }
94}
95
96impl<T: FromWireOptionRef<W>, W> FromWireRef<W> for Option<T> {
97 fn from_wire_ref(wire: &W) -> Self {
98 T::from_wire_option_ref(wire)
99 }
100}