1use crate::{
4 boxed::{ArchivedBox, BoxResolver},
5 ser::Serializer,
6 ArchivePointee, ArchiveUnsized, SerializeUnsized,
7};
8use core::{
9 cmp::{self, Eq, Ord, PartialEq, PartialOrd},
10 fmt, hash,
11 hint::unreachable_unchecked,
12 ops::Deref,
13 pin::Pin,
14};
15
16#[repr(transparent)]
20pub struct ArchivedOptionBox<T: ArchivePointee + ?Sized> {
21 inner: ArchivedBox<T>,
22}
23
24impl<T: ArchivePointee + ?Sized> ArchivedOptionBox<T> {
25 #[inline]
27 pub fn is_none(&self) -> bool {
28 self.as_ref().is_none()
29 }
30
31 #[inline]
33 pub fn is_some(&self) -> bool {
34 self.as_ref().is_some()
35 }
36
37 #[inline]
39 pub fn as_ref(&self) -> Option<&ArchivedBox<T>> {
40 if self.inner.is_null() {
41 None
42 } else {
43 Some(&self.inner)
44 }
45 }
46
47 #[inline]
49 pub fn as_mut(&mut self) -> Option<&mut ArchivedBox<T>> {
50 if self.inner.is_null() {
51 None
52 } else {
53 Some(&mut self.inner)
54 }
55 }
56
57 #[inline]
59 pub fn as_pin_ref(self: Pin<&Self>) -> Option<Pin<&ArchivedBox<T>>> {
60 unsafe { Pin::get_ref(self).as_ref().map(|x| Pin::new_unchecked(x)) }
61 }
62
63 #[inline]
65 pub fn as_pin_mut(self: Pin<&mut Self>) -> Option<Pin<&mut ArchivedBox<T>>> {
66 unsafe {
67 Pin::get_unchecked_mut(self)
68 .as_mut()
69 .map(|x| Pin::new_unchecked(x))
70 }
71 }
72
73 #[inline]
75 pub fn iter(&self) -> Iter<'_, ArchivedBox<T>> {
76 Iter {
77 inner: self.as_ref(),
78 }
79 }
80
81 #[inline]
83 pub fn iter_mut(&mut self) -> IterMut<'_, ArchivedBox<T>> {
84 IterMut {
85 inner: self.as_mut(),
86 }
87 }
88
89 #[inline]
94 pub fn as_deref(&self) -> Option<&T> {
95 self.as_ref().map(|x| (*x).deref())
96 }
97}
98
99impl<T: ArchivePointee + ?Sized> ArchivedOptionBox<T>
100where
101 T::ArchivedMetadata: Default,
102{
103 #[inline]
110 pub unsafe fn resolve_from_option<U: ArchiveUnsized<Archived = T> + ?Sized>(
111 field: Option<&U>,
112 pos: usize,
113 resolver: OptionBoxResolver<U::MetadataResolver>,
114 out: *mut Self,
115 ) {
116 let (fp, fo) = out_field!(out.inner);
117 if let Some(value) = field {
118 let resolver = if let OptionBoxResolver::Some(metadata_resolver) = resolver {
119 metadata_resolver
120 } else {
121 unreachable_unchecked();
122 };
123
124 ArchivedBox::resolve_from_ref(value, pos + fp, resolver, fo)
125 } else {
126 ArchivedBox::emplace_null(pos + fp, fo);
127 }
128 }
129
130 #[inline]
132 pub fn serialize_from_option<U, S>(
133 field: Option<&U>,
134 serializer: &mut S,
135 ) -> Result<OptionBoxResolver<U::MetadataResolver>, S::Error>
136 where
137 U: SerializeUnsized<S, Archived = T> + ?Sized,
138 S: Serializer + ?Sized,
139 {
140 if let Some(value) = field {
141 Ok(OptionBoxResolver::Some(ArchivedBox::serialize_from_ref(
142 value, serializer,
143 )?))
144 } else {
145 Ok(OptionBoxResolver::None)
146 }
147 }
148}
149
150impl<T: ArchivePointee + ?Sized> fmt::Debug for ArchivedOptionBox<T>
151where
152 T::ArchivedMetadata: fmt::Debug,
153{
154 #[inline]
155 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
156 match self.as_ref() {
157 Some(inner) => inner.fmt(f),
158 None => f.debug_tuple("None").finish(),
159 }
160 }
161}
162
163impl<T: ArchivePointee + Eq + ?Sized> Eq for ArchivedOptionBox<T> {}
164
165impl<T: ArchivePointee + hash::Hash + ?Sized> hash::Hash for ArchivedOptionBox<T> {
166 #[inline]
167 fn hash<H: hash::Hasher>(&self, state: &mut H) {
168 self.as_ref().hash(state)
169 }
170}
171
172impl<T: ArchivePointee + Ord + ?Sized> Ord for ArchivedOptionBox<T> {
173 #[inline]
174 fn cmp(&self, other: &Self) -> cmp::Ordering {
175 self.as_ref().cmp(&other.as_ref())
176 }
177}
178
179impl<T: ArchivePointee + PartialEq + ?Sized> PartialEq for ArchivedOptionBox<T> {
180 #[inline]
181 fn eq(&self, other: &Self) -> bool {
182 self.as_ref().eq(&other.as_ref())
183 }
184}
185
186impl<T: ArchivePointee + PartialOrd + ?Sized> PartialOrd for ArchivedOptionBox<T> {
187 #[inline]
188 fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
189 self.as_ref().partial_cmp(&other.as_ref())
190 }
191}
192
193pub type Iter<'a, T> = crate::option::Iter<'a, T>;
199
200pub type IterMut<'a, T> = crate::option::IterMut<'a, T>;
206
207pub enum OptionBoxResolver<T> {
209 None,
211 Some(BoxResolver<T>),
213}