rkyv/niche/
option_nonzero.rs1use core::{
4 cmp, fmt, hash,
5 num::{
6 NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8,
7 NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8,
8 },
9};
10
11use munge::munge;
12
13use crate::{seal::Seal, traits::NoUndef, Archived, Place, Portable};
14
15macro_rules! impl_archived_option_nonzero {
16 ($ar:ident, $nz:ty, $ne:ty) => {
17 #[doc = concat!("A niched archived `Option<", stringify!($nz), ">`")]
18 #[derive(Copy, Clone, Portable)]
19 #[rkyv(crate)]
20 #[repr(transparent)]
21 #[cfg_attr(feature = "bytecheck", derive(bytecheck::CheckBytes))]
22 pub struct $ar {
23 inner: Archived<$ne>,
24 }
25
26 impl $ar {
27 #[inline]
29 pub fn is_none(&self) -> bool {
30 self.inner == 0
31 }
32
33 #[inline]
35 pub fn is_some(&self) -> bool {
36 self.inner != 0
37 }
38
39 #[rustfmt::skip]
40 #[doc = concat!(
41 "Converts to an `Option<&Archived<",
42 stringify!($nz),
43 ">>`"
44 )]
45 #[inline]
46 pub fn as_ref(&self) -> Option<&Archived<$nz>> {
47 if self.inner != 0 {
48 let as_nonzero = unsafe {
49 &*(&self.inner as *const _ as *const Archived<$nz>)
53 };
54 Some(as_nonzero)
55 } else {
56 None
57 }
58 }
59
60 #[rustfmt::skip]
61 #[doc = concat!(
62 "Converts to an `Option<&mut Archived<",
63 stringify!($nz),
64 ">>`",
65 )]
66 #[inline]
67 pub fn as_mut(&mut self) -> Option<&mut Archived<$nz>> {
68 if self.inner != 0 {
69 let as_nonzero = unsafe {
70 &mut *(&mut self.inner as *mut _ as *mut Archived<$nz>)
74 };
75 Some(as_nonzero)
76 } else {
77 None
78 }
79 }
80
81 #[rustfmt::skip]
82 #[doc = concat!(
83 "Converts from `Seal<'_, ArchivedOption",
84 stringify!($nz),
85 ">` to `Option<Seal<'_, Archived<",
86 stringify!($nz),
87 ">>>`.",
88 )]
89 #[inline]
90 pub fn as_seal(
91 this: Seal<'_, Self>,
92 ) -> Option<Seal<'_, Archived<$nz>>> {
93 let this = unsafe { Seal::unseal_unchecked(this) };
94 this.as_mut().map(Seal::new)
95 }
96
97 #[inline]
100 pub fn take(&mut self) -> Option<Archived<$nz>> {
101 if self.inner != 0 {
102 let result = unsafe {
104 Archived::<$nz>::new_unchecked(self.inner.into())
105 };
106 self.inner = 0.into();
107 Some(result)
108 } else {
109 None
110 }
111 }
112
113 #[inline]
115 pub fn iter(&self) -> Iter<&'_ Archived<$nz>> {
116 Iter::new(self.as_ref())
117 }
118
119 #[inline]
121 pub fn iter_mut(&mut self) -> Iter<&'_ mut Archived<$nz>> {
122 Iter::new(self.as_mut())
123 }
124
125 #[inline]
128 pub fn iter_seal(
129 this: Seal<'_, Self>,
130 ) -> Iter<Seal<'_, Archived<$nz>>> {
131 Iter::new(Self::as_seal(this))
132 }
133
134 #[inline]
137 pub fn get_or_insert(&mut self, v: $nz) -> &mut Archived<$nz> {
138 self.get_or_insert_with(move || v)
139 }
140
141 pub fn get_or_insert_with<F>(&mut self, f: F) -> &mut Archived<$nz>
144 where
145 F: FnOnce() -> $nz,
146 {
147 if self.inner == 0 {
148 self.inner = f().get().into();
149 }
150 unsafe {
151 &mut *(&mut self.inner as *mut _ as *mut Archived<$nz>)
153 }
154 }
155
156 #[inline]
158 pub fn resolve_from_option(
159 field: Option<$nz>,
160 out: Place<Self>,
161 ) {
162 munge!(let Self { inner } = out);
163 if let Some(nz) = field {
164 inner.write(nz.get().into());
165 } else {
166 inner.write((0 as $ne).into());
167 }
168 }
169 }
170
171 impl fmt::Debug for $ar {
172 #[inline]
173 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
174 self.as_ref().fmt(f)
175 }
176 }
177
178 impl Eq for $ar {}
179
180 impl hash::Hash for $ar {
181 fn hash<H: hash::Hasher>(&self, state: &mut H) {
182 self.as_ref().hash(state)
183 }
184 }
185
186 impl Ord for $ar {
187 #[inline]
188 fn cmp(&self, other: &Self) -> cmp::Ordering {
189 self.as_ref().cmp(&other.as_ref())
190 }
191 }
192
193 impl PartialEq for $ar {
194 #[inline]
195 fn eq(&self, other: &Self) -> bool {
196 self.as_ref().eq(&other.as_ref())
197 }
198 }
199
200 impl PartialOrd for $ar {
201 #[inline]
202 fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
203 Some(self.cmp(other))
204 }
205 }
206
207 unsafe impl NoUndef for $ar {}
208 };
209}
210
211impl_archived_option_nonzero!(ArchivedOptionNonZeroI8, NonZeroI8, i8);
212impl_archived_option_nonzero!(ArchivedOptionNonZeroI16, NonZeroI16, i16);
213impl_archived_option_nonzero!(ArchivedOptionNonZeroI32, NonZeroI32, i32);
214impl_archived_option_nonzero!(ArchivedOptionNonZeroI64, NonZeroI64, i64);
215impl_archived_option_nonzero!(ArchivedOptionNonZeroI128, NonZeroI128, i128);
216
217pub type ArchivedOptionNonZeroIsize = match_pointer_width!(
219 ArchivedOptionNonZeroI16,
220 ArchivedOptionNonZeroI32,
221 ArchivedOptionNonZeroI64,
222);
223
224impl_archived_option_nonzero!(ArchivedOptionNonZeroU8, NonZeroU8, u8);
225impl_archived_option_nonzero!(ArchivedOptionNonZeroU16, NonZeroU16, u16);
226impl_archived_option_nonzero!(ArchivedOptionNonZeroU32, NonZeroU32, u32);
227impl_archived_option_nonzero!(ArchivedOptionNonZeroU64, NonZeroU64, u64);
228impl_archived_option_nonzero!(ArchivedOptionNonZeroU128, NonZeroU128, u128);
229
230pub type ArchivedOptionNonZeroUsize = match_pointer_width!(
232 ArchivedOptionNonZeroU16,
233 ArchivedOptionNonZeroU32,
234 ArchivedOptionNonZeroU64,
235);
236
237pub type Iter<P> = crate::option::Iter<P>;