//! Common parsing utilities for derive macros. //! //! Fair parsing of [`syn::Type`] and [`syn::Expr`] requires [`syn`]'s `full` //! feature to be enabled, which unnecessary increases compile times. As we //! don't have complex AST manipulation, usually requiring only understanding //! where syntax item begins and ends, simpler manual parsing is implemented.
use proc_macro2::{Delimiter, Spacing, TokenStream}; use quote::ToTokens; use syn::{
buffer::Cursor,
parse::{Parse, ParseStream},
punctuated::Punctuated,
spanned::Spanned as _,
token, Error, Ident, Result,
};
/// Every other [`syn::Expr`] variant.
Other(TokenStream),
}
impl Expr { /// Returns an [`Ident`] in case this [`Expr`] is represented only by it. pub(crate) fn ident(&self) -> Option<&Ident> { matchself { Self::Ident(ident) => Some(ident), Self::Other(_) => None,
}
}
}
let (stream, c) = parser(cursor)?;
out.extend(stream);
cursor = c;
parsed = true;
}
}
}
#[cfg(test)] mod spec { use std::{fmt::Debug, str::FromStr};
use itertools::Itertools as _; use proc_macro2::TokenStream; use quote::ToTokens; use syn::{
parse::{Parse, Parser as _},
punctuated::Punctuated,
token::Comma,
};
#[test] fn cases() { let cases = [ "[Type ; 3]", "fn (usize) -> bool", "for <'a > fn (&'a usize) -> bool", "(Type)", "path :: to :: Type", "path :: to :: Generic < Type >", "< Type as Trait >:: Assoc", "< Type as Trait >:: Assoc < GAT >", "* const ()", "* mut ()", "& i32", "&'static str", "& [str]", "dyn Trait", "dyn Trait + Send", "()", "(Type ,)", "(Type , Type)", "(Type , Type ,)",
];
assert::<Type>("", []); for i in1..4 { for permutations in cases.into_iter().permutations(i) { letmut input = permutations.join(",");
assert::<Type>(&input, &permutations);
input.push(',');
assert::<Type>(&input, &permutations);
}
}
}
}
mod expr { usesuper::*;
#[test] fn cases() { let cases = [ "ident", "[a , b , c , d]", "counter += 1", "async { fut . await }", "a < b", "a > b", "{ let x = (a , b) ; }", "invoke (a , b)", "foo as f64", "| a , b | a + b", "obj . k", "for pat in expr { break pat ; }", "if expr { true } else { false }", "vector [2]", "1", "\"foo\"", "loop { break i ; }", "format ! (\"{}\" , q)", "match n { Some (n) => { } , None => { } }", "x . foo ::< T > (a , b)", "x . foo ::< T < [T < T >; if a < b { 1 } else { 2 }] >, { a < b } > (a , b)", "(a + b)", "i32 :: MAX", "1 .. 2", "& a", "[0u8 ; N]", "(a , b , c , d)", "< Ty as Trait > :: T", "< Ty < Ty < T >, { a < b } > as Trait < T > > :: T",
];
assert::<Expr>("", []); for i in1..4 { for permutations in cases.into_iter().permutations(i) { letmut input = permutations.clone().join(",");
assert::<Expr>(&input, &permutations);
input.push(',');
assert::<Expr>(&input, &permutations);
}
}
}
}
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.12 Sekunden
(vorverarbeitet am 2026-06-22)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.