debug fmt

This commit is contained in:
nora 2022-09-12 08:12:29 +02:00
parent 86441cf10b
commit 1152f8ab99
2 changed files with 58 additions and 15 deletions

View file

@ -1,3 +1,4 @@
use core::panic;
use std::{iter::Peekable, str::Chars};
use proc_macro::TokenStream;
@ -58,21 +59,48 @@ impl<'a, I> Formatter<'a, I>
where
I: Iterator<Item = Expr>,
{
fn expect_expr(&mut self) -> Expr {
self.exprs
.next()
.expect("missing argument for display formatting")
}
fn expect_char(&mut self, char: char) {
let next = self.string.next();
if next != Some(char) {
panic!(
"expected {char}, found {}",
next.map(|c| c.to_string())
.unwrap_or_else(|| "end of input".to_string())
);
}
}
fn parse(mut self) -> Vec<FmtPart> {
let mut next_string = String::new();
while let Some(char) = self.string.next() {
match char {
'{' => {
self.save_string(std::mem::take(&mut next_string));
if self.string.next() != Some('}') {
panic!("only supports display formatting!");
'{' => match self.string.next() {
Some('}') => {
self.save_string(std::mem::take(&mut next_string));
let expr = self.expect_expr();
self.fmt_parts.push(FmtPart::Display(expr));
}
let expr = self
.exprs
.next()
.expect("missing argument for display formatting");
self.fmt_parts.push(FmtPart::Display(expr));
}
Some(':') => {
self.save_string(std::mem::take(&mut next_string));
self.expect_char('?');
self.expect_char('}');
let expr = self.expect_expr();
self.fmt_parts.push(FmtPart::Debug(expr))
}
Some(other) => {
panic!("expected }}, found '{}'", other)
}
None => {
panic!("expected '}}'")
}
},
other => {
next_string.push(other);
}
@ -96,13 +124,13 @@ impl ToTokens for FmtPart {
let own_tokens = match self {
FmtPart::Literal(lit) => {
let literal = LitStr::new(lit, Span::call_site());
quote! { mono_fmt::_private::Str(#literal) }
quote! { ::mono_fmt::_private::Str(#literal) }
}
FmtPart::Display(expr) => {
quote! { mono_fmt::_private::DisplayArg(#expr) }
quote! { ::mono_fmt::_private::DisplayArg(#expr) }
}
FmtPart::Debug(expr) => {
quote! { mono_fmt::_private::DebugArg(#expr) }
quote! { ::mono_fmt::_private::DebugArg(#expr) }
}
};

View file

@ -1,3 +1,7 @@
// for the test macro expansion
#[cfg(test)]
extern crate self as mono_fmt;
pub use mono_fmt_macro::format_args;
use std::fmt::{Error, Write};
@ -136,8 +140,6 @@ macro_rules! format {
#[cfg(test)]
mod tests {
// for the macros
use crate as mono_fmt;
use crate::format;
@ -152,4 +154,17 @@ mod tests {
let result = format!("{}", "uwu");
assert_eq!(result, "uwu");
}
#[test]
fn display_with_strings() {
let result = format!("oow{} omg", "uwu");
assert_eq!(result, "oowuwu omg");
}
#[test]
fn debug() {
let result = format!("test {:?} hello", "uwu");
assert_eq!(result, r#"test "uwu" hello"#);
}
}