From 8f990a4477aa126e6bc79b98ba5f6685b0658fe7 Mon Sep 17 00:00:00 2001 From: HampusM Date: Sun, 13 Aug 2023 11:26:37 +0200 Subject: feat: add internal logging for macros --- macros/src/util/mod.rs | 1 + macros/src/util/tokens.rs | 89 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+) create mode 100644 macros/src/util/tokens.rs (limited to 'macros/src/util') diff --git a/macros/src/util/mod.rs b/macros/src/util/mod.rs index d3edb67..2244229 100644 --- a/macros/src/util/mod.rs +++ b/macros/src/util/mod.rs @@ -3,6 +3,7 @@ pub mod item_impl; pub mod iterator_ext; pub mod string; pub mod syn_path; +pub mod tokens; macro_rules! to_option { ($($tokens: tt)+) => { diff --git a/macros/src/util/tokens.rs b/macros/src/util/tokens.rs new file mode 100644 index 0000000..c614ea0 --- /dev/null +++ b/macros/src/util/tokens.rs @@ -0,0 +1,89 @@ +use std::fmt::Write; + +use proc_macro2::{Delimiter, Spacing, TokenTree}; +use quote::ToTokens; + +pub trait ToTokensExt +{ + fn to_str_pretty(&self) -> String; +} + +impl ToTokensExt for T +{ + fn to_str_pretty(&self) -> String + { + let mut spaceable = Spaceable::None; + + self.to_token_stream() + .into_iter() + .fold(String::new(), |mut acc, token_tree| { + let prev_spaceable = spaceable; + + spaceable = get_tt_spaceable(&token_tree); + + if matches!(prev_spaceable, Spaceable::Left | Spaceable::LeftRight) + && matches!(spaceable, Spaceable::Right | Spaceable::LeftRight) + { + write!(acc, " ").ok(); + } + + match token_tree { + TokenTree::Group(group) => match group.delimiter() { + Delimiter::Parenthesis => { + write!(acc, "({})", group.stream().to_str_pretty()).ok(); + } + Delimiter::Brace => { + write!(acc, "{{{}}}", group.stream().to_str_pretty()).ok(); + } + Delimiter::Bracket => { + write!(acc, "[{}]", group.stream().to_str_pretty()).ok(); + } + Delimiter::None => { + write!(acc, "{}", group.stream().to_str_pretty()).ok(); + } + }, + tt => { + write!(acc, "{tt}").ok(); + } + } + + acc + }) + } +} + +fn get_tt_spaceable(token_tree: &TokenTree) -> Spaceable +{ + match &token_tree { + TokenTree::Ident(_) => Spaceable::LeftRight, + TokenTree::Punct(punct) + if punct.spacing() == Spacing::Alone && (punct.as_char() == '+') => + { + Spaceable::LeftRight + } + TokenTree::Punct(punct) + if punct.spacing() == Spacing::Alone + && (punct.as_char() == '>' || punct.as_char() == ',') => + { + Spaceable::Left + } + TokenTree::Punct(punct) + if punct.spacing() == Spacing::Joint && punct.as_char() == '-' => + { + // Is part of -> + Spaceable::Right + } + TokenTree::Punct(punct) if punct.as_char() == '&' => Spaceable::Right, + TokenTree::Group(_) => Spaceable::Left, + _ => Spaceable::None, + } +} + +#[derive(Debug, Clone, Copy)] +enum Spaceable +{ + Left, + Right, + LeftRight, + None, +} -- cgit v1.2.3-18-g5258