fidl_next_codec/copy_optimization.rs
1// Copyright 2025 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::marker::PhantomData;
6
7/// An optimization hint about whether the conversion from `T` to `U` is equivalent to copying the
8/// raw bytes of `T`.
9pub struct CopyOptimization<T: ?Sized, U: ?Sized>(bool, PhantomData<(*mut T, *mut U)>);
10
11impl<T: ?Sized, U: ?Sized> CopyOptimization<T, U> {
12 /// Returns a `CopyOptimization` hint with the optimization enabled.
13 ///
14 /// # Safety
15 ///
16 /// `T` and `U` must be the same size and must not have any uninit bytes (e.g. padding).
17 pub const unsafe fn enable() -> Self {
18 Self(true, PhantomData)
19 }
20
21 /// Returns a `CopyOptimization` hint with the optimization enabled if `value` is `true`.
22 ///
23 /// # Safety
24 ///
25 /// `T` and `U` must be the same size and must not have any uninit bytes (e.g. padding) if
26 /// `value` is `true`.
27 pub const unsafe fn enable_if(value: bool) -> Self {
28 Self(value, PhantomData)
29 }
30
31 /// Returns a `CopyOptimization` hint with the optimization disabled.
32 pub const fn disable() -> Self {
33 Self(false, PhantomData)
34 }
35
36 /// Returns whether the optimization is enabled.
37 pub const fn is_enabled(&self) -> bool {
38 self.0
39 }
40
41 /// Infers whether the conversion from `[T; N]` to `[U; N]` is copy-optimizable based on the
42 /// conversion from `T` to `U`.
43 pub const fn infer_array<const N: usize>(&self) -> CopyOptimization<[T; N], [U; N]>
44 where
45 T: Sized,
46 U: Sized,
47 {
48 unsafe { CopyOptimization::enable_if(self.is_enabled()) }
49 }
50
51 /// Infers whether the conversion from `[T]` to `[U]` is copy-optimizable based on the
52 /// conversion from `T` to `U`.
53 pub const fn infer_slice(&self) -> CopyOptimization<[T], [U]>
54 where
55 T: Sized,
56 U: Sized,
57 {
58 unsafe { CopyOptimization::enable_if(self.is_enabled()) }
59 }
60}
61
62impl<T: ?Sized> CopyOptimization<T, T> {
63 /// Returns an enabled `CopyOptimization`, as copy optimization is always enabled from a type to
64 /// itself.
65 pub const fn identity() -> Self {
66 unsafe { Self::enable() }
67 }
68}