numbers, yee haw

This commit is contained in:
nora 2022-09-13 21:58:30 +02:00
parent 166b495586
commit 81f0b8d9cd
6 changed files with 414 additions and 227 deletions

View file

@ -1,31 +1,96 @@
use crate::Formatter;
#[derive(Debug, Clone, Copy)]
pub enum Alignment {
Left,
Center,
Right,
Unknown,
}
pub trait FmtOpts {
#[doc(hidden)]
type Inner: FmtOpts;
macro_rules! options {
(
$(
fn $name:ident() -> $ret:ty {
$($default:tt)*
}
)*
) => {
pub trait FmtOpts {
#[doc(hidden)]
type Inner: FmtOpts;
$(
#[inline]
fn $name() -> $ret {
Self::Inner::$name()
}
)*
}
impl FmtOpts for () {
type Inner = never::Never;
$(
#[inline]
fn $name() -> $ret {
$($default)*
}
)*
}
impl<W, O: FmtOpts> Formatter<W, O> {
$(
#[inline]
pub fn $name(&self) -> $ret {
O::$name()
}
)*
}
};
}
options!(
fn alternate() -> bool {
Self::Inner::alternate()
false
}
fn width() -> Option<usize> {
Self::Inner::width()
None
}
fn align() -> Option<Alignment> {
Self::Inner::align()
fn align() -> Alignment {
Alignment::Unknown
}
fn fill() -> Option<char> {
Self::Inner::fill()
fn fill() -> char {
' '
}
}
fn sign_plus() -> bool {
false
}
fn sign_aware_zero_pad() -> bool {
false
}
fn sign_minus() -> bool {
false
}
fn precision() -> Option<usize> {
None
}
fn debug_lower_hex() -> bool {
false
}
fn debug_upper_hex() -> bool {
false
}
);
mod never {
use crate::FmtOpts;
@ -45,29 +110,11 @@ mod never {
}
}
impl FmtOpts for () {
type Inner = never::Never;
fn alternate() -> bool {
false
}
fn width() -> Option<usize> {
None
}
fn align() -> Option<Alignment> {
None
}
fn fill() -> Option<char> {
None
}
}
pub struct WithAlternate<I>(pub I);
impl<I: FmtOpts> FmtOpts for WithAlternate<I> {
type Inner = I;
#[inline]
fn alternate() -> bool {
true
}
@ -76,6 +123,7 @@ pub struct WithWidth<I, const A: usize>(pub I);
impl<I: FmtOpts, const A: usize> FmtOpts for WithWidth<I, A> {
type Inner = I;
#[inline]
fn width() -> Option<usize> {
Some(A)
}
@ -84,91 +132,35 @@ pub struct WithLeftAlign<I>(pub I);
impl<I: FmtOpts> FmtOpts for WithLeftAlign<I> {
type Inner = I;
fn align() -> Option<Alignment> {
Some(Alignment::Left)
#[inline]
fn align() -> Alignment {
Alignment::Left
}
}
pub struct WithRightAlign<I>(pub I);
impl<I: FmtOpts> FmtOpts for WithRightAlign<I> {
type Inner = I;
fn align() -> Option<Alignment> {
Some(Alignment::Right)
#[inline]
fn align() -> Alignment {
Alignment::Right
}
}
pub struct WithCenterAlign<I>(pub I);
impl<I: FmtOpts> FmtOpts for WithCenterAlign<I> {
type Inner = I;
fn align() -> Option<Alignment> {
Some(Alignment::Center)
#[inline]
fn align() -> Alignment {
Alignment::Center
}
}
pub struct WithFill<I, const A: char>(pub I);
impl<I: FmtOpts, const A: char> FmtOpts for WithFill<I, A> {
type Inner = I;
fn fill() -> Option<char> {
Some(A)
}
}
impl<W, O: FmtOpts> Formatter<W, O> {
pub fn alternate(&self) -> bool {
O::alternate()
}
pub fn width() -> Option<usize> {
O::width()
}
pub fn align() -> Option<Alignment> {
O::align()
}
pub fn fill() -> Option<char> {
O::fill()
}
pub fn with_alternate(self) -> Formatter<W, WithAlternate<O>> {
Formatter {
buf: self.buf,
opts: WithAlternate(self.opts),
}
}
pub fn with_width<const WIDTH: usize>(self) -> Formatter<W, WithWidth<O, WIDTH>> {
Formatter {
buf: self.buf,
opts: WithWidth(self.opts),
}
}
pub fn with_left_align(self) -> Formatter<W, WithLeftAlign<O>> {
Formatter {
buf: self.buf,
opts: WithLeftAlign(self.opts),
}
}
pub fn with_right_align(self) -> Formatter<W, WithRightAlign<O>> {
Formatter {
buf: self.buf,
opts: WithRightAlign(self.opts),
}
}
pub fn with_center_align(self) -> Formatter<W, WithCenterAlign<O>> {
Formatter {
buf: self.buf,
opts: WithCenterAlign(self.opts),
}
}
pub fn with_fill<const FILL: char>(self) -> Formatter<W, WithFill<O, FILL>> {
Formatter {
buf: self.buf,
opts: WithFill(self.opts),
}
#[inline]
fn fill() -> char {
A
}
}