1#![warn(missing_docs)]
4#![cfg_attr(doc, allow(unknown_lints))]
6#![deny(rustdoc::all)]
7
8use serde::{de::DeserializeSeed, Deserializer};
9
10macro_rules! pub_use {
12 () => {
13 pub use crate::{asset::*, cid::*, handle::*, io::*, network_handle::*, server::*};
14 pub use anyhow;
15 pub use bones_schema::prelude::*;
16 pub use dashmap;
17 pub use futures_lite::future::Boxed as BoxedFuture;
18 pub use path_absolutize::Absolutize;
19 pub use semver::Version;
20 };
21}
22pub_use!();
23
24pub mod prelude {
26 pub_use!();
27 pub use super::{Maybe, Maybe::*};
28}
29
30mod asset;
31mod cid;
32mod handle;
33mod io;
34mod network_handle;
35mod parse;
36mod server;
37
38#[derive(HasSchema, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Default, Debug)]
40#[type_data(SchemaMetaAssetLoader(maybe_loader))]
41#[repr(C, u8)]
42pub enum Maybe<T> {
43 #[default]
45 Unset,
46 Set(T),
48}
49
50impl<T> Maybe<T> {
51 #[inline]
53 pub fn option(self) -> Option<T> {
54 self.into()
55 }
56
57 #[inline]
59 pub fn is_set(&self) -> bool {
60 matches!(self, Maybe::Set(_))
61 }
62
63 #[inline]
65 pub fn is_unset(&self) -> bool {
66 matches!(self, Maybe::Unset)
67 }
68
69 #[inline]
71 pub fn is_some(&self) -> bool {
72 matches!(self, Maybe::Set(_))
73 }
74
75 #[inline]
77 pub fn is_none(&self) -> bool {
78 matches!(self, Maybe::Unset)
79 }
80
81 #[inline]
83 pub fn contains<U>(&self, x: &U) -> bool
84 where
85 U: PartialEq<T>,
86 {
87 match self {
88 Maybe::Set(y) => x == y,
89 Maybe::Unset => false,
90 }
91 }
92
93 #[inline]
95 pub fn as_ref(&self) -> Maybe<&T> {
96 match *self {
97 Maybe::Unset => Maybe::Unset,
98 Maybe::Set(ref x) => Maybe::Set(x),
99 }
100 }
101
102 #[inline]
104 pub fn as_mut(&mut self) -> Maybe<&mut T> {
105 match *self {
106 Maybe::Unset => Maybe::Unset,
107 Maybe::Set(ref mut x) => Maybe::Set(x),
108 }
109 }
110
111 #[inline]
113 #[track_caller]
114 pub fn expect(self, msg: &str) -> T {
115 self.option().expect(msg)
116 }
117
118 #[inline]
120 #[track_caller]
121 pub fn unwrap(self) -> T {
122 self.option().unwrap()
123 }
124
125 #[inline]
127 pub fn unwrap_or(self, default: T) -> T {
128 self.option().unwrap_or(default)
129 }
130
131 #[inline]
133 pub fn unwrap_or_else<F: FnOnce() -> T>(self, f: F) -> T {
134 self.option().unwrap_or_else(f)
135 }
136
137 #[inline]
139 pub fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Maybe<U> {
140 self.option().map(f).into()
141 }
142
143 #[inline]
145 pub fn and_then<U, F: FnOnce(T) -> Maybe<U>>(self, f: F) -> Maybe<U> {
146 self.option().and_then(|x| f(x).option()).into()
147 }
148
149 #[inline]
151 pub fn and<U>(self, optb: Maybe<U>) -> Maybe<U> {
152 self.option().and(optb.option()).into()
153 }
154
155 #[inline]
157 pub fn filter<P: FnOnce(&T) -> bool>(self, predicate: P) -> Maybe<T> {
158 self.option().filter(predicate).into()
159 }
160
161 #[inline]
163 pub fn or(self, optb: Maybe<T>) -> Maybe<T> {
164 self.option().or(optb.option()).into()
165 }
166
167 #[inline]
169 pub fn or_else<F: FnOnce() -> Maybe<T>>(self, f: F) -> Maybe<T> {
170 self.option().or_else(|| f().option()).into()
171 }
172
173 #[inline]
175 pub fn xor(self, optb: Maybe<T>) -> Maybe<T> {
176 self.option().xor(optb.option()).into()
177 }
178
179 #[inline]
181 pub fn get_or_insert(&mut self, v: T) -> &mut T {
182 if let Maybe::Unset = self {
183 *self = Maybe::Set(v);
184 }
185 match self {
186 Maybe::Set(ref mut v) => v,
187 Maybe::Unset => unreachable!(),
188 }
189 }
190
191 #[inline]
193 pub fn get_or_insert_with<F: FnOnce() -> T>(&mut self, f: F) -> &mut T {
194 if let Maybe::Unset = self {
195 *self = Maybe::Set(f());
196 }
197 match self {
198 Maybe::Set(ref mut v) => v,
199 Maybe::Unset => unreachable!(),
200 }
201 }
202
203 #[inline]
205 pub fn take(&mut self) -> Maybe<T> {
206 std::mem::replace(self, Maybe::Unset)
207 }
208
209 #[inline]
211 pub fn replace(&mut self, value: T) -> Maybe<T> {
212 std::mem::replace(self, Maybe::Set(value))
213 }
214
215 #[inline]
217 pub fn zip<U>(self, other: Maybe<U>) -> Maybe<(T, U)> {
218 self.option().zip(other.option()).into()
219 }
220
221 #[inline]
227 pub unsafe fn unwrap_unchecked(self) -> T {
228 self.option().unwrap_unchecked()
229 }
230
231 #[inline]
233 pub fn map_or<U, F: FnOnce(T) -> U>(self, default: U, f: F) -> U {
234 self.option().map_or(default, f)
235 }
236
237 #[inline]
239 pub fn map_or_else<U, D: FnOnce() -> U, F: FnOnce(T) -> U>(self, default: D, f: F) -> U {
240 self.option().map_or_else(default, f)
241 }
242
243 #[inline]
245 pub fn unwrap_or_default(self) -> T
246 where
247 T: Default,
248 {
249 self.option().unwrap_or_default()
250 }
251
252 #[inline]
254 pub fn ok_or<E>(self, err: E) -> Result<T, E> {
255 self.option().ok_or(err)
256 }
257
258 #[inline]
260 pub fn ok_or_else<E, F: FnOnce() -> E>(self, err: F) -> Result<T, E> {
261 self.option().ok_or_else(err)
262 }
263}
264
265impl<T> From<Maybe<T>> for Option<T> {
266 #[inline]
267 fn from(value: Maybe<T>) -> Self {
268 match value {
269 Maybe::Set(s) => Some(s),
270 Maybe::Unset => None,
271 }
272 }
273}
274
275impl<T> From<Option<T>> for Maybe<T> {
276 #[inline]
277 fn from(value: Option<T>) -> Self {
278 match value {
279 Some(s) => Maybe::Set(s),
280 None => Maybe::Unset,
281 }
282 }
283}
284
285fn maybe_loader(
286 ctx: &mut MetaAssetLoadCtx,
287 ptr: SchemaRefMut<'_>,
288 deserialzer: &mut dyn erased_serde::Deserializer,
289) -> anyhow::Result<()> {
290 deserialzer.deserialize_option(MaybeVisitor { ctx, ptr })?;
291
292 Ok(())
293}
294
295struct MaybeVisitor<'a, 'srv> {
296 ctx: &'a mut MetaAssetLoadCtx<'srv>,
297 ptr: SchemaRefMut<'a>,
298}
299
300impl<'a, 'srv, 'de> serde::de::Visitor<'de> for MaybeVisitor<'a, 'srv> {
301 type Value = ();
302
303 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
304 write!(formatter, "an optional value")
305 }
306
307 fn visit_unit<E>(self) -> Result<Self::Value, E>
308 where
309 E: serde::de::Error,
310 {
311 Ok(())
312 }
313 fn visit_none<E>(self) -> Result<Self::Value, E>
314 where
315 E: serde::de::Error,
316 {
317 Ok(())
318 }
319
320 fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
321 where
322 D: Deserializer<'de>,
323 {
324 unsafe {
327 self.ptr.as_ptr().cast::<u8>().write(1);
328 }
329
330 let value_offset = self.ptr.schema().field_offsets()[0].1;
332 let value_schema = self.ptr.schema().kind.as_enum().unwrap().variants[1]
336 .schema
337 .kind
338 .as_struct()
339 .unwrap()
340 .fields[0]
341 .schema;
342 let value_ref = unsafe {
344 SchemaRefMut::from_ptr_schema(self.ptr.as_ptr().add(value_offset), value_schema)
345 };
346
347 SchemaPtrLoadCtx {
349 ctx: self.ctx,
350 ptr: value_ref,
351 }
352 .deserialize(deserializer)
353 }
354}