use std::{fmt, marker::PhantomData};
use crate::sealed::Sealed;
pub trait OptionalField: Sealed {
#[doc(hidden)]
type Storage<T: fmt::Debug + Copy>: FieldStorage<T>;
}
#[allow(missing_debug_implementations)]
pub enum StoreField {}
impl Sealed for StoreField {}
impl OptionalField for StoreField {
type Storage<T: fmt::Debug + Copy> = StoredField<T>;
}
#[allow(missing_debug_implementations)]
pub enum OmitField {}
impl Sealed for OmitField {}
impl OptionalField for OmitField {
type Storage<T: fmt::Debug + Copy> = OmittedField<T>;
}
pub trait FieldStorage<T>: From<T> + fmt::Debug + Copy {
fn into_option(self) -> Option<T>;
}
#[derive(Clone, Copy, Debug)]
pub struct StoredField<T>(T);
impl<T: Copy + fmt::Debug> FieldStorage<T> for StoredField<T> {
#[inline(always)]
fn into_option(self) -> Option<T> {
Some(self.0)
}
}
impl<T> From<T> for StoredField<T> {
#[inline(always)]
fn from(value: T) -> Self {
Self(value)
}
}
#[derive(Clone, Copy, Debug)]
pub struct OmittedField<T>(PhantomData<T>);
impl<T: Copy + fmt::Debug> FieldStorage<T> for OmittedField<T> {
#[inline(always)]
fn into_option(self) -> Option<T> {
None
}
}
impl<T> From<T> for OmittedField<T> {
#[inline(always)]
fn from(_: T) -> Self {
Self(PhantomData)
}
}