mirror of
https://github.com/Noratrieb/mono-fmt.git
synced 2026-01-14 15:25:08 +01:00
oh yes
This commit is contained in:
parent
83331e5326
commit
ce5aa95a09
4 changed files with 199 additions and 6 deletions
|
|
@ -1,3 +1,9 @@
|
|||
[workspace]
|
||||
members = [
|
||||
".",
|
||||
"mono-fmt-macro"
|
||||
]
|
||||
|
||||
[package]
|
||||
name = "mono-fmt"
|
||||
version = "0.1.0"
|
||||
|
|
@ -6,3 +12,4 @@ edition = "2021"
|
|||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
mono-fmt-macro = { path = "./mono-fmt-macro" }
|
||||
13
mono-fmt-macro/Cargo.toml
Normal file
13
mono-fmt-macro/Cargo.toml
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
[package]
|
||||
name = "mono-fmt-macro"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[lib]
|
||||
proc-macro = true
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
quote = "1.0.21"
|
||||
syn = "1.0.99"
|
||||
31
mono-fmt-macro/src/lib.rs
Normal file
31
mono-fmt-macro/src/lib.rs
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
use proc_macro::TokenStream;
|
||||
use quote::quote;
|
||||
use syn::{
|
||||
parse::{Parse, ParseStream},
|
||||
Expr, parse_macro_input,
|
||||
};
|
||||
|
||||
struct Input {
|
||||
format_str: String,
|
||||
items: Vec<Expr>,
|
||||
}
|
||||
|
||||
impl Parse for Input {
|
||||
fn parse(input: ParseStream) -> syn::Result<Self> {
|
||||
let first = input.parse::<syn::LitStr>()?;
|
||||
Ok(Self {
|
||||
format_str: first.value(),
|
||||
items: Vec::new(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[proc_macro]
|
||||
pub fn format_args(tokens: TokenStream) -> TokenStream {
|
||||
let input = parse_macro_input!(tokens as Input);
|
||||
let str = input.format_str;
|
||||
quote! {
|
||||
(mono_fmt::_private::Str(#str),)
|
||||
}
|
||||
.into()
|
||||
}
|
||||
154
src/lib.rs
154
src/lib.rs
|
|
@ -1,14 +1,156 @@
|
|||
pub fn add(left: usize, right: usize) -> usize {
|
||||
left + right
|
||||
pub use mono_fmt_macro::format_args;
|
||||
use std::fmt::{Error, Write};
|
||||
|
||||
use crate::arguments::Arguments;
|
||||
|
||||
pub type Result = std::result::Result<(), Error>;
|
||||
|
||||
trait Debug {
|
||||
fn fmt<W: Write>(&self, f: &mut Formatter<W>) -> Result;
|
||||
}
|
||||
|
||||
trait Display {
|
||||
fn fmt<W: Write>(&self, f: &mut Formatter<W>) -> Result;
|
||||
}
|
||||
|
||||
impl Debug for &'_ str {
|
||||
fn fmt<W: Write>(&self, f: &mut Formatter<W>) -> Result {
|
||||
f.write_char('"')?;
|
||||
f.write_str(self)?;
|
||||
f.write_char('"')
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for &'_ str {
|
||||
fn fmt<W: Write>(&self, f: &mut Formatter<W>) -> Result {
|
||||
f.write_str(self)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Formatter<W> {
|
||||
buf: W,
|
||||
}
|
||||
|
||||
impl<W> Formatter<W> {
|
||||
fn new(buf: W) -> Self {
|
||||
Self { buf }
|
||||
}
|
||||
}
|
||||
|
||||
impl<W: Write> Formatter<W> {
|
||||
pub fn write_char(&mut self, char: char) -> Result {
|
||||
self.buf.write_char(char)
|
||||
}
|
||||
|
||||
pub fn write_str(&mut self, str: &str) -> Result {
|
||||
self.buf.write_str(str)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn format<A: Arguments>(args: A) -> String {
|
||||
let mut string = String::new();
|
||||
let mut fmt = Formatter::new(&mut string);
|
||||
args.fmt(&mut fmt).unwrap();
|
||||
string
|
||||
}
|
||||
|
||||
mod arguments {
|
||||
use crate::{Debug, Display, Formatter, Result};
|
||||
use std::fmt::Write;
|
||||
pub trait Arguments {
|
||||
fn fmt<W: Write>(&self, f: &mut Formatter<W>) -> Result;
|
||||
}
|
||||
|
||||
macro_rules! impl_arguments {
|
||||
() => {};
|
||||
($first:ident $($rest:ident)*) => {
|
||||
impl<$first, $($rest),*> Arguments for ($first, $($rest),*)
|
||||
where
|
||||
$first: Arguments,
|
||||
$($rest: Arguments),*
|
||||
{
|
||||
#[allow(non_snake_case)]
|
||||
fn fmt<W: Write>(&self, f: &mut Formatter<W>) -> Result {
|
||||
let ($first, $($rest),*) = self;
|
||||
Arguments::fmt($first, f)?;
|
||||
$(
|
||||
Arguments::fmt($rest, f)?;
|
||||
)*
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl_arguments!($($rest)*);
|
||||
};
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
impl_arguments!(
|
||||
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
|
||||
// A31 A32 A33 A34 A35 A36 A37 A38 A39 A40
|
||||
// A41 A42 A43 A44 A45 A46 A47 A48 A49 A50
|
||||
// A51 A52 A53 A54 A55 A56 A57 A58 A59 A60
|
||||
// A61 A62 A63 A64 A65 A66 A67 A68 A69 A70
|
||||
// A71 A72 A73 A74 A75 A76 A77 A78 A79 A80
|
||||
// A81 A82 A83 A84 A85 A86 A87 A88 A89 A90
|
||||
// A91 A92 A93 A94 A95 A96 A97 A98 A99 A100
|
||||
);
|
||||
|
||||
pub struct Str(pub &'static str);
|
||||
|
||||
impl Arguments for Str {
|
||||
fn fmt<W: Write>(&self, f: &mut Formatter<W>) -> Result {
|
||||
f.write_str(self.0)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct DebugArg<T>(pub T);
|
||||
|
||||
impl<T: Debug> Arguments for DebugArg<T> {
|
||||
fn fmt<W: Write>(&self, f: &mut Formatter<W>) -> Result {
|
||||
Debug::fmt(&self.0, f)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct DisplayArg<T>(pub T);
|
||||
|
||||
impl<T: Display> Arguments for DisplayArg<T> {
|
||||
fn fmt<W: Write>(&self, f: &mut Formatter<W>) -> Result {
|
||||
Display::fmt(&self.0, f)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod _private {
|
||||
pub use super::arguments::{DebugArg, DisplayArg, Str};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! format {
|
||||
($($tt:tt)*) => {
|
||||
$crate::format($crate::format_args!($($tt)*))
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
// for the macros
|
||||
use crate as mono_fmt;
|
||||
|
||||
use crate::arguments::DebugArg;
|
||||
use crate::format;
|
||||
|
||||
#[test]
|
||||
fn it_works() {
|
||||
let result = add(2, 2);
|
||||
assert_eq!(result, 4);
|
||||
fn hello_world() {
|
||||
let result = format!("Hello, World");
|
||||
assert_eq!(result, "Hello, World");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn debug() {
|
||||
let result = format((DebugArg("uwu"),));
|
||||
assert_eq!(result, "\"uwu\"");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue