#![warn(missing_docs)]
#![cfg_attr(doc, allow(unknown_lints))]
#![deny(rustdoc::all)]
use serde::{de::DeserializeSeed, Deserializer};
macro_rules! pub_use {
() => {
pub use crate::{asset::*, cid::*, handle::*, io::*, network_handle::*, server::*};
pub use anyhow;
pub use bones_schema::prelude::*;
pub use dashmap;
pub use path_absolutize::Absolutize;
pub use semver::Version;
};
}
pub_use!();
pub mod prelude {
pub_use!();
pub use super::{Maybe, Maybe::*};
}
mod asset;
mod cid;
mod handle;
mod io;
mod network_handle;
mod parse;
mod server;
#[derive(HasSchema, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Default, Debug)]
#[type_data(SchemaMetaAssetLoader(maybe_loader))]
#[repr(C, u8)]
pub enum Maybe<T> {
#[default]
Unset,
Set(T),
}
impl<T> Maybe<T> {
pub fn option(self) -> Option<T> {
self.into()
}
}
impl<T> From<Maybe<T>> for Option<T> {
fn from(value: Maybe<T>) -> Self {
match value {
Maybe::Set(s) => Some(s),
Maybe::Unset => None,
}
}
}
impl<T> From<Option<T>> for Maybe<T> {
fn from(value: Option<T>) -> Self {
match value {
Some(s) => Maybe::Set(s),
None => Maybe::Unset,
}
}
}
fn maybe_loader(
ctx: &mut MetaAssetLoadCtx,
ptr: SchemaRefMut<'_>,
deserialzer: &mut dyn erased_serde::Deserializer,
) -> anyhow::Result<()> {
deserialzer.deserialize_option(MaybeVisitor { ctx, ptr })?;
Ok(())
}
struct MaybeVisitor<'a, 'srv> {
ctx: &'a mut MetaAssetLoadCtx<'srv>,
ptr: SchemaRefMut<'a>,
}
impl<'a, 'srv, 'de> serde::de::Visitor<'de> for MaybeVisitor<'a, 'srv> {
type Value = ();
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(formatter, "an optional value")
}
fn visit_unit<E>(self) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(())
}
fn visit_none<E>(self) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(())
}
fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: Deserializer<'de>,
{
unsafe {
self.ptr.as_ptr().cast::<u8>().write(1);
}
let value_offset = self.ptr.schema().field_offsets()[0].1;
let value_schema = self.ptr.schema().kind.as_enum().unwrap().variants[1]
.schema
.kind
.as_struct()
.unwrap()
.fields[0]
.schema;
let value_ref = unsafe {
SchemaRefMut::from_ptr_schema(self.ptr.as_ptr().add(value_offset), value_schema)
};
SchemaPtrLoadCtx {
ctx: self.ctx,
ptr: value_ref,
}
.deserialize(deserializer)
}
}