mirror of
https://github.com/Noratrieb/mono-fmt.git
synced 2026-01-16 00:05:05 +01:00
rewrite
This commit is contained in:
parent
2f7a13cb2f
commit
594047c0a1
8 changed files with 444 additions and 620 deletions
68
src/args.rs
68
src/args.rs
|
|
@ -1,11 +1,9 @@
|
|||
use std::marker::PhantomData;
|
||||
|
||||
use crate::{Debug, Display, FmtOpts, Formatter, Result, Write};
|
||||
use crate::{FmtOpts, Formatter, Result, Write};
|
||||
pub trait Arguments {
|
||||
fn fmt<W: Write, O: FmtOpts>(&self, f: &mut Formatter<W, O>) -> Result;
|
||||
}
|
||||
|
||||
macro_rules! impl_arguments {
|
||||
macro_rules! tuple_args {
|
||||
() => {};
|
||||
($first:ident $($rest:ident)*) => {
|
||||
impl<$first, $($rest),*> Arguments for ($first, $($rest),*)
|
||||
|
|
@ -24,12 +22,12 @@ macro_rules! impl_arguments {
|
|||
}
|
||||
}
|
||||
|
||||
impl_arguments!($($rest)*);
|
||||
tuple_args!($($rest)*);
|
||||
};
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
impl_arguments!(
|
||||
tuple_args!(
|
||||
A1 A2 A3 A4 A5 A6 A7 A8 A9 A10
|
||||
// A11 A12 A13 A14 A15 A16 A17 A18 A19 A20
|
||||
// A21 A22 A23 A24 A25 A26 A27 A28 A29 A30
|
||||
|
|
@ -50,37 +48,33 @@ impl Arguments for Str {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct DebugArg<T, O>(pub T, pub PhantomData<O>);
|
||||
macro_rules! traits {
|
||||
($(struct $name:ident: trait $trait:ident);* $(;)?) => {
|
||||
$(
|
||||
pub struct $name<T, O>(pub T, pub O);
|
||||
|
||||
impl<T: Debug, OutOpt> Arguments for DebugArg<T, OutOpt> {
|
||||
fn fmt<W: Write, O: FmtOpts>(&self, f: &mut Formatter<W, O>) -> Result {
|
||||
Debug::fmt(&self.0, f)
|
||||
}
|
||||
pub trait $trait {
|
||||
fn fmt<W: Write, O: FmtOpts>(&self, f: &mut Formatter<W, O>) -> Result;
|
||||
}
|
||||
|
||||
impl<T: $trait, O: FmtOpts> Arguments for $name<T, O> {
|
||||
fn fmt<W: Write, OldOpts: FmtOpts>(&self, f: &mut Formatter<W, OldOpts>) -> Result {
|
||||
let mut f = f.with_opts(&self.1);
|
||||
|
||||
<T as $trait>::fmt(&self.0, &mut f)
|
||||
}
|
||||
}
|
||||
)*
|
||||
};
|
||||
}
|
||||
|
||||
pub struct DisplayArg<T, O>(pub T, pub PhantomData<O>);
|
||||
|
||||
impl<T: Display, OutOpt> Arguments for DisplayArg<T, OutOpt> {
|
||||
fn fmt<W: Write, O: FmtOpts>(&self, f: &mut Formatter<W, O>) -> Result {
|
||||
Display::fmt(&self.0, f)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ConstWidthArg<T, const WIDTH: usize> {
|
||||
value: T,
|
||||
_boo: PhantomData<[(); WIDTH]>,
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
pub fn ConstWidthArg<T, const WIDTH: usize>(value: T) -> ConstWidthArg<T, WIDTH> {
|
||||
ConstWidthArg {
|
||||
value,
|
||||
_boo: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Display, const WIDTH: usize> Arguments for ConstWidthArg<T, WIDTH> {
|
||||
fn fmt<W: Write, O: FmtOpts>(&self, _: &mut Formatter<W, O>) -> Result {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
traits!(
|
||||
struct DebugArg: trait Debug;
|
||||
struct DisplayArg: trait Display;
|
||||
struct BinaryArg: trait Binary;
|
||||
struct OctalArg: trait Octal;
|
||||
struct LowerHexArg: trait LowerHex;
|
||||
struct UpperHexArg: trait UpperHex;
|
||||
struct UpperExpArg: trait UpperExp;
|
||||
struct LowerExpArg: trait LowerExp;
|
||||
);
|
||||
|
|
|
|||
59
src/lib.rs
59
src/lib.rs
|
|
@ -12,7 +12,10 @@ macro_rules! format_args {
|
|||
};
|
||||
}
|
||||
|
||||
pub use crate::{args::Arguments, opts::FmtOpts};
|
||||
pub use crate::{
|
||||
args::{Arguments, Binary, Debug, Display, LowerExp, LowerHex, Octal, UpperExp, UpperHex},
|
||||
opts::FmtOpts,
|
||||
};
|
||||
|
||||
pub type Result = std::result::Result<(), Error>;
|
||||
|
||||
|
|
@ -46,33 +49,6 @@ impl<W: Write> Write for &mut W {
|
|||
}
|
||||
}
|
||||
|
||||
pub trait Debug {
|
||||
fn fmt<W: Write, O: FmtOpts>(&self, f: &mut Formatter<W, O>) -> Result;
|
||||
}
|
||||
|
||||
pub trait Display {
|
||||
fn fmt<W: Write, O: FmtOpts>(&self, f: &mut Formatter<W, O>) -> Result;
|
||||
}
|
||||
|
||||
pub trait Binary {
|
||||
fn fmt<W: Write, O: FmtOpts>(&self, f: &mut Formatter<W, O>) -> Result;
|
||||
}
|
||||
pub trait Octal {
|
||||
fn fmt<W: Write, O: FmtOpts>(&self, f: &mut Formatter<W, O>) -> Result;
|
||||
}
|
||||
pub trait LowerHex {
|
||||
fn fmt<W: Write, O: FmtOpts>(&self, f: &mut Formatter<W, O>) -> Result;
|
||||
}
|
||||
pub trait UpperHex {
|
||||
fn fmt<W: Write, O: FmtOpts>(&self, f: &mut Formatter<W, O>) -> Result;
|
||||
}
|
||||
pub trait UpperExp {
|
||||
fn fmt<W: Write, O: FmtOpts>(&self, f: &mut Formatter<W, O>) -> Result;
|
||||
}
|
||||
pub trait LowerExp {
|
||||
fn fmt<W: Write, O: FmtOpts>(&self, f: &mut Formatter<W, O>) -> Result;
|
||||
}
|
||||
|
||||
pub struct Formatter<W, O> {
|
||||
buf: W,
|
||||
opts: O,
|
||||
|
|
@ -103,6 +79,15 @@ impl<W: Write, O: FmtOpts> Formatter<W, O> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<W, O> Formatter<W, O> {
|
||||
fn with_opts<'opt, ONew>(&mut self, opts: &'opt ONew) -> Formatter<&mut W, &'opt ONew> {
|
||||
Formatter {
|
||||
buf: &mut self.buf,
|
||||
opts,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write<W: Write, A: Arguments>(buffer: W, args: A) -> Result {
|
||||
let mut fmt = Formatter::new(buffer);
|
||||
args.fmt(&mut fmt)
|
||||
|
|
@ -120,10 +105,11 @@ mod _private {
|
|||
pub use mono_fmt_macro::__format_args;
|
||||
|
||||
pub use crate::{
|
||||
args::{ConstWidthArg, DebugArg, DisplayArg, Str},
|
||||
opts::{
|
||||
WithAlternate, WithFill, WithAlign, WithWidth,
|
||||
args::{
|
||||
BinaryArg, DebugArg, DisplayArg, LowerExpArg, LowerHexArg, OctalArg, Str, UpperExpArg,
|
||||
UpperHexArg,
|
||||
},
|
||||
opts::{WithAlign, WithAlternate, WithFill, WithWidth},
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -168,3 +154,14 @@ mod tests {
|
|||
assert_eq!(result, "a: 32523532");
|
||||
}
|
||||
}
|
||||
|
||||
fn fmt() {
|
||||
let a = (
|
||||
_private::Str("amount: "),
|
||||
_private::DebugArg::<_, _private::WithAlternate<()>>(5, _private::WithAlternate(())),
|
||||
);
|
||||
|
||||
let mut str = String::new();
|
||||
let mut f = Formatter::new(&mut str);
|
||||
Arguments::fmt(&a, &mut f).unwrap();
|
||||
}
|
||||
|
|
|
|||
58
src/opts.rs
58
src/opts.rs
|
|
@ -11,7 +11,7 @@ pub enum Alignment {
|
|||
macro_rules! options {
|
||||
(
|
||||
$(
|
||||
fn $name:ident() -> $ret:ty {
|
||||
fn $name:ident(&self) -> $ret:ty {
|
||||
$($default:tt)*
|
||||
}
|
||||
|
||||
|
|
@ -24,10 +24,12 @@ macro_rules! options {
|
|||
#[doc(hidden)]
|
||||
type Inner: FmtOpts;
|
||||
|
||||
fn inner(&self) -> &Self::Inner;
|
||||
|
||||
$(
|
||||
#[inline]
|
||||
fn $name() -> $ret {
|
||||
Self::Inner::$name()
|
||||
fn $name(&self) -> $ret {
|
||||
Self::Inner::$name(Self::inner(self))
|
||||
}
|
||||
)*
|
||||
}
|
||||
|
|
@ -35,19 +37,39 @@ macro_rules! options {
|
|||
impl FmtOpts for () {
|
||||
type Inner = Self;
|
||||
|
||||
fn inner(&self) -> &Self::Inner {
|
||||
self
|
||||
}
|
||||
|
||||
$(
|
||||
#[inline]
|
||||
fn $name() -> $ret {
|
||||
fn $name(&self) -> $ret {
|
||||
$($default)*
|
||||
}
|
||||
)*
|
||||
}
|
||||
|
||||
impl<O: FmtOpts> FmtOpts for &'_ O {
|
||||
type Inner = O::Inner;
|
||||
|
||||
fn inner(&self) -> &Self::Inner {
|
||||
O::inner(self)
|
||||
}
|
||||
|
||||
$(
|
||||
#[inline]
|
||||
fn $name(&self) -> $ret {
|
||||
O::$name(self)
|
||||
}
|
||||
)*
|
||||
}
|
||||
|
||||
|
||||
impl<W, O: FmtOpts> Formatter<W, O> {
|
||||
$(
|
||||
#[inline]
|
||||
pub fn $name(&self) -> $ret {
|
||||
O::$name()
|
||||
O::$name(&self.opts)
|
||||
}
|
||||
)*
|
||||
}
|
||||
|
|
@ -58,7 +80,11 @@ macro_rules! options {
|
|||
impl<I: FmtOpts, $($(const $const_gen_name: $with_ty),*)?> FmtOpts for $with_name<I, $($($const_gen_name),*)?> {
|
||||
type Inner = I;
|
||||
|
||||
fn $name() -> $ret {
|
||||
fn inner(&self) -> &Self::Inner {
|
||||
&self.0
|
||||
}
|
||||
|
||||
fn $name(&self) -> $ret {
|
||||
$($struct_body)*
|
||||
}
|
||||
}
|
||||
|
|
@ -67,21 +93,21 @@ macro_rules! options {
|
|||
}
|
||||
|
||||
options!(
|
||||
fn alternate() -> bool {
|
||||
fn alternate(&self) -> bool {
|
||||
false
|
||||
}
|
||||
struct WithAlternate {
|
||||
true
|
||||
}
|
||||
|
||||
fn width() -> Option<usize> {
|
||||
fn width(&self) -> Option<usize> {
|
||||
None
|
||||
}
|
||||
struct WithWidth<const A: usize> {
|
||||
Some(A)
|
||||
}
|
||||
|
||||
fn align() -> Alignment {
|
||||
fn align(&self) -> Alignment {
|
||||
Alignment::Unknown
|
||||
}
|
||||
struct WithAlign<const A: usize> {
|
||||
|
|
@ -95,49 +121,49 @@ options!(
|
|||
}
|
||||
|
||||
|
||||
fn fill() -> char {
|
||||
fn fill(&self) -> char {
|
||||
' '
|
||||
}
|
||||
struct WithFill<const A: char> {
|
||||
A
|
||||
}
|
||||
|
||||
fn sign_plus() -> bool {
|
||||
fn sign_plus(&self) -> bool {
|
||||
false
|
||||
}
|
||||
struct WithSignPlus {
|
||||
true
|
||||
}
|
||||
|
||||
fn sign_aware_zero_pad() -> bool {
|
||||
fn sign_aware_zero_pad(&self) -> bool {
|
||||
false
|
||||
}
|
||||
struct WithSignAwareZeroPad {
|
||||
true
|
||||
}
|
||||
|
||||
fn sign_minus() -> bool {
|
||||
fn sign_minus(&self) -> bool {
|
||||
false
|
||||
}
|
||||
struct WithMinus {
|
||||
true
|
||||
}
|
||||
|
||||
fn precision() -> Option<usize> {
|
||||
fn precision(&self) -> Option<usize> {
|
||||
None
|
||||
}
|
||||
struct WithPrecision<const A: usize> {
|
||||
Some(A)
|
||||
}
|
||||
|
||||
fn debug_lower_hex() -> bool {
|
||||
fn debug_lower_hex(&self) -> bool {
|
||||
false
|
||||
}
|
||||
struct WithDebugLowerHex {
|
||||
true
|
||||
}
|
||||
|
||||
fn debug_upper_hex() -> bool {
|
||||
fn debug_upper_hex(&self) -> bool {
|
||||
false
|
||||
}
|
||||
struct WithDebugUpperHex {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue