rkyv/niche/
option_nonzero.rs1use crate::Archived;
4use core::{
5 cmp, fmt, hash,
6 num::{
7 NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroU128, NonZeroU16,
8 NonZeroU32, NonZeroU64, NonZeroU8,
9 },
10 pin::Pin,
11};
12
13macro_rules! impl_archived_option_nonzero {
14 ($ar:ident, $nz:ty, $ne:ty) => {
15 #[doc = concat!("A niched archived `Option<", stringify!($nz), ">`")]
16 #[repr(transparent)]
17 pub struct $ar {
18 inner: Archived<$ne>,
19 }
20
21 impl $ar {
22 #[inline]
24 pub fn is_none(&self) -> bool {
25 self.inner == 0
26 }
27
28 #[inline]
30 pub fn is_some(&self) -> bool {
31 self.inner != 0
32 }
33
34 #[doc = concat!("Converts to an `Option<&Archived<", stringify!($nz), ">>`")]
35 pub fn as_ref(&self) -> Option<&Archived<$nz>> {
36 if self.inner != 0 {
37 let as_nonzero = unsafe {
38 &*(&self.inner as *const _ as *const Archived<$nz>)
41 };
42 Some(as_nonzero)
43 } else {
44 None
45 }
46 }
47
48 #[doc = concat!("Converts to an `Option<&mut Archived<", stringify!($nz), ">>`")]
49 pub fn as_mut(&mut self) -> Option<&mut Archived<$nz>> {
50 if self.inner != 0 {
51 let as_nonzero = unsafe {
52 &mut *(&mut self.inner as *mut _ as *mut Archived<$nz>)
55 };
56 Some(as_nonzero)
57 } else {
58 None
59 }
60 }
61
62 #[doc = concat!("Converts from `Pin<&ArchivedOption", stringify!($nz), ">` to `Option<Pin<&Archived<", stringify!($nz), ">>>`.")]
63 #[inline]
64 pub fn as_pin_ref(self: Pin<&Self>) -> Option<Pin<&Archived<$nz>>> {
65 unsafe { Pin::get_ref(self).as_ref().map(|x| Pin::new_unchecked(x)) }
66 }
67
68 #[doc = concat!("Converts from `Pin<&mut ArchivedOption", stringify!($nz), ">` to `Option<Pin<&mut Archived<", stringify!($nz), ">>>`.")]
69 #[inline]
70 pub fn as_pin_mut(self: Pin<&mut Self>) -> Option<Pin<&mut Archived<$nz>>> {
71 unsafe {
72 Pin::get_unchecked_mut(self)
73 .as_mut()
74 .map(|x| Pin::new_unchecked(x))
75 }
76 }
77
78 #[inline]
80 pub fn iter(&self) -> Iter<'_, Archived<$nz>> {
81 Iter {
82 inner: self.as_ref(),
83 }
84 }
85
86 #[inline]
88 pub fn iter_mut(&mut self) -> IterMut<'_, Archived<$nz>> {
89 IterMut {
90 inner: self.as_mut(),
91 }
92 }
93
94 #[inline]
97 pub fn get_or_insert(&mut self, v: $nz) -> &mut Archived<$nz> {
98 self.get_or_insert_with(move || v)
99 }
100
101 #[inline]
104 pub fn get_or_insert_with<F: FnOnce() -> $nz>(&mut self, f: F) -> &mut Archived<$nz> {
105 if self.inner == 0 {
106 self.inner = f().get().into();
107 }
108 unsafe {
109 &mut *(&mut self.inner as *mut _ as *mut Archived<$nz>)
111 }
112 }
113
114 #[inline]
120 pub unsafe fn resolve_from_option(field: Option<$nz>, out: *mut Self) {
121 let (_, fo) = out_field!(out.inner);
122 if let Some(nz) = field {
123 fo.write(nz.get().into());
124 } else {
125 fo.write((0 as $ne).into());
126 }
127 }
128 }
129
130 impl fmt::Debug for $ar {
131 #[inline]
132 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
133 match self.as_ref() {
134 Some(inner) => inner.fmt(f),
135 None => f.debug_tuple("None").finish(),
136 }
137 }
138 }
139
140 impl Eq for $ar {}
141
142 impl hash::Hash for $ar {
143 #[inline]
144 fn hash<H: hash::Hasher>(&self, state: &mut H) {
145 self.as_ref().hash(state)
146 }
147 }
148
149 impl Ord for $ar {
150 #[inline]
151 fn cmp(&self, other: &Self) -> cmp::Ordering {
152 self.as_ref().cmp(&other.as_ref())
153 }
154 }
155
156 impl PartialEq for $ar {
157 #[inline]
158 fn eq(&self, other: &Self) -> bool {
159 self.as_ref().eq(&other.as_ref())
160 }
161 }
162
163 impl PartialOrd for $ar {
164 #[inline]
165 fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
166 Some(self.cmp(other))
167 }
168 }
169 };
170}
171
172impl_archived_option_nonzero!(ArchivedOptionNonZeroI8, NonZeroI8, i8);
173impl_archived_option_nonzero!(ArchivedOptionNonZeroI16, NonZeroI16, i16);
174impl_archived_option_nonzero!(ArchivedOptionNonZeroI32, NonZeroI32, i32);
175impl_archived_option_nonzero!(ArchivedOptionNonZeroI64, NonZeroI64, i64);
176impl_archived_option_nonzero!(ArchivedOptionNonZeroI128, NonZeroI128, i128);
177
178impl_archived_option_nonzero!(ArchivedOptionNonZeroU8, NonZeroU8, u8);
179impl_archived_option_nonzero!(ArchivedOptionNonZeroU16, NonZeroU16, u16);
180impl_archived_option_nonzero!(ArchivedOptionNonZeroU32, NonZeroU32, u32);
181impl_archived_option_nonzero!(ArchivedOptionNonZeroU64, NonZeroU64, u64);
182impl_archived_option_nonzero!(ArchivedOptionNonZeroU128, NonZeroU128, u128);
183
184pub type Iter<'a, T> = crate::option::Iter<'a, T>;
189
190pub type IterMut<'a, T> = crate::option::IterMut<'a, T>;