use crate::{Unit, Width};
use core::fmt::{Display, Error, Formatter};
use fmt_iter::repeat;
pub trait Pad<Value: Width, PadBlock: Display> {
fn fmt(
&self,
formatter: &mut Formatter<'_>,
value: &Value,
pad_block: &PadBlock,
pad_width: usize,
) -> Result<(), Error>;
}
impl<Value, PadBlock, X> Pad<Value, PadBlock> for &X
where
Value: Width,
PadBlock: Display,
X: Pad<Value, PadBlock> + Sized,
{
fn fmt(
&self,
formatter: &mut Formatter<'_>,
value: &Value,
pad_block: &PadBlock,
pad_width: usize,
) -> Result<(), Error> {
X::fmt(*self, formatter, value, pad_block, pad_width)
}
}
pub trait UnitPad<Value: Width, PadBlock: Display>: Unit + Pad<Value, PadBlock> {}
macro_rules! unit_pad {
($name:ident) => {
impl Unit for $name {
const VALUE: Self = $name;
}
impl<Value: Width, PadBlock: Display> UnitPad<Value, PadBlock> for $name {}
};
}
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
pub struct AlignLeft;
unit_pad!(AlignLeft);
impl<Value: Width, PadBlock: Display> Pad<Value, PadBlock> for AlignLeft {
fn fmt(
&self,
formatter: &mut Formatter<'_>,
value: &Value,
pad_block: &PadBlock,
pad_width: usize,
) -> Result<(), Error> {
let pad = repeat(pad_block, pad_width);
write!(formatter, "{}{}", value, pad)
}
}
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
pub struct AlignRight;
unit_pad!(AlignRight);
impl<Value: Width, PadBlock: Display> Pad<Value, PadBlock> for AlignRight {
fn fmt(
&self,
formatter: &mut Formatter<'_>,
value: &Value,
pad_block: &PadBlock,
pad_width: usize,
) -> Result<(), Error> {
let pad = repeat(pad_block, pad_width);
write!(formatter, "{}{}", pad, value)
}
}
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
pub struct AlignCenterLeft;
unit_pad!(AlignCenterLeft);
impl<Value: Width, PadBlock: Display> Pad<Value, PadBlock> for AlignCenterLeft {
fn fmt(
&self,
formatter: &mut Formatter<'_>,
value: &Value,
pad_block: &PadBlock,
pad_width: usize,
) -> Result<(), Error> {
let pad = repeat(pad_block, pad_width >> 1);
let remainder = repeat(pad_block, pad_width & 1);
write!(formatter, "{}{}{}{}", pad, value, pad, remainder)
}
}
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
pub struct AlignCenterRight;
unit_pad!(AlignCenterRight);
impl<Value: Width, PadBlock: Display> Pad<Value, PadBlock> for AlignCenterRight {
fn fmt(
&self,
formatter: &mut Formatter<'_>,
value: &Value,
pad_block: &PadBlock,
pad_width: usize,
) -> Result<(), Error> {
let pad = repeat(pad_block, pad_width >> 1);
let remainder = repeat(pad_block, pad_width & 1);
write!(formatter, "{}{}{}{}", pad, remainder, value, pad)
}
}