use core::marker::PhantomData;
use super::{Display, Format, Result, Style, Write};
#[derive(Clone, Copy)]
pub struct Arguments<'a>(pub &'a [Var<'a>]);
type FmtFn<T, S> = fn(&T, &mut dyn Write, &S) -> Result;
type DynFmtFn = unsafe fn(
*const (), &mut dyn Write,
*const (), ) -> Result;
impl Arguments<'_> {
pub fn write(&self, f: &mut dyn Write) -> Result {
for var in self.0 {
var.call(f)?;
}
Ok(())
}
}
crate::stylable!(for('a) Arguments<'a>);
impl Format<Display> for Arguments<'_> {
fn fmt(&self, f: &mut dyn Write, _: &Display) -> Result {
self.write(f)
}
}
pub struct Var<'a> {
data: *const (),
style: *const (),
func: DynFmtFn,
_lt: PhantomData<&'a ()>,
}
impl<'a> Var<'a> {
pub fn new<T, S>(data: &'a T, style: &'a S) -> Var<'a>
where
T: Format<S>,
S: Style,
{
Self {
data: data as *const T as *const (),
style: style as *const S as *const (),
func: unsafe {
core::mem::transmute::<FmtFn<T, S>, DynFmtFn>(<T as Format<S>>::fmt as FmtFn<T, S>)
},
_lt: PhantomData,
}
}
pub fn call(&self, f: &mut dyn Write) -> Result {
unsafe { (self.func)(self.data, f, self.style) }
}
}