use super::{
Reader,
Writer, };
use crate::{
fmt,
prelude::*,
uaccess::UserSliceReader, };
use core::{
marker::PhantomData,
ops::Deref, };
pub(crate) unsafe trait Adapter {
type Inner;
}
#[repr(transparent)]
pub(crate) struct WritableAdapter<D, W> {
inner: D,
_writer: PhantomData<W>,
}
unsafe impl<D, W> Adapter for WritableAdapter<D, W> {
type Inner = D;
}
impl<D: Writer, W> Writer for WritableAdapter<D, W> {
fn write(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
self.inner.write(fmt)
}
}
impl<D: Deref, W> Reader for WritableAdapter<D, W>
where
W: Fn(&D::Target, &mut UserSliceReader) -> Result + Send + Sync + 'static,
{
fn read_from_slice(&self, reader: &mut UserSliceReader) -> Result {
let w: &W = unsafe { materialize_zst() };
w(self.inner.deref(), reader)
}
}
#[repr(transparent)]
pub(crate) struct FormatAdapter<D, F> {
inner: D,
_formatter: PhantomData<F>,
}
impl<D, F> Deref for FormatAdapter<D, F> {
type Target = D;
fn deref(&self) -> &D {
&self.inner
}
}
impl<D, F> Writer for FormatAdapter<D, F>
where
F: Fn(&D, &mut fmt::Formatter<'_>) -> fmt::Result + 'static,
{
fn write(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
let f: &F = unsafe { materialize_zst() };
f(&self.inner, fmt)
}
}
unsafe impl<D, F> Adapter for FormatAdapter<D, F> {
type Inner = D;
}
#[repr(transparent)]
pub(crate) struct NoWriter<D> {
inner: D,
}
unsafe impl<D> Adapter for NoWriter<D> {
type Inner = D;
}
impl<D> Deref for NoWriter<D> {
type Target = D;
fn deref(&self) -> &D {
&self.inner
}
}
unsafe fn materialize_zst<F>() -> &'static F {
const { assert!(core::mem::size_of::<F>() == 0) };
let zst_dangle: core::ptr::NonNull<F> = core::ptr::NonNull::dangling();
unsafe { zst_dangle.as_ref() }
}