#![doc = include_str!("../README.md")]
extern crate alloc;
use ::alloc::vec::Vec;
use ::core::{
fmt::Debug,
ops::{
Deref,
DerefMut,
},
};
use ::proc_macro2::{
Delimiter,
Group,
Ident,
Literal,
Punct,
Span,
TokenStream,
TokenTree,
extra::DelimSpan,
};
#[derive(Clone, Debug)]
pub struct GroupWithMetadata<G, I = G, P = G, L = I> {
pub delimiter: Delimiter,
pub contents: TokenWithMetadataVec<G, I, P, L>,
pub span: Span,
pub metadata: G,
}
impl<G, I, P, L> GroupWithMetadata<G, I, P, L> {
#[must_use = "If you meant to drop this value, use `std::mem::drop` instead."]
pub fn strip_metadata(self) -> Group {
let mut group = Group::new(
self.delimiter,
token_with_metadata_iter_ext::iter_tokens_strip_metadata(self.contents).collect(),
);
group.set_span(self.span);
group
}
#[inline(always)]
#[deprecated(note = "Use the `delimiter` field directly.")]
pub fn delimiter(&self) -> Delimiter {
self.delimiter
}
#[inline(always)]
#[must_use]
#[deprecated(note = "Use the `span` field directly.")]
pub fn span(&self) -> Span {
self.span
}
#[must_use]
pub fn span_open(&self) -> Span {
let mut dummy = Group::new(self.delimiter, TokenStream::new());
dummy.set_span(self.span);
dummy.span_open()
}
#[must_use]
pub fn span_close(&self) -> Span {
let mut dummy = Group::new(self.delimiter, TokenStream::new());
dummy.set_span(self.span);
dummy.span_close()
}
#[must_use]
pub fn delim_span(&self) -> DelimSpan {
let mut dummy = Group::new(self.delimiter, TokenStream::new());
dummy.set_span(self.span);
dummy.delim_span()
}
#[inline(always)]
#[deprecated(note = "Use the `span` field directly.")]
pub fn set_span(&mut self, span: Span) {
self.span = span;
}
}
impl<G, I, P, L> From<Group> for GroupWithMetadata<G, I, P, L>
where
G: Default,
I: Default,
P: Default,
L: Default,
{
fn from(value: Group) -> Self {
Self {
delimiter: value.delimiter(),
contents: token_with_metadata_iter_ext::iter_tokens_add_default_metadata(value.stream()).collect(),
span: value.span(),
metadata: G::default(),
}
}
}
impl<T> From<(Group, &T)> for GroupWithMetadata<T>
where
T: Clone,
{
fn from((value, metadata): (Group, &T)) -> Self {
Self {
delimiter: value.delimiter(),
contents: token_with_metadata_iter_ext::iter_tokens_add_metadata(value.stream(), metadata).collect(),
span: value.span(),
metadata: metadata.clone(),
}
}
}
impl<G, I, P, L> From<(Group, &G, &I, &P, &L)> for GroupWithMetadata<G, I, P, L>
where
G: Clone,
I: Clone,
P: Clone,
L: Clone,
{
fn from((value, g, i, p, l): (Group, &G, &I, &P, &L)) -> Self {
Self {
delimiter: value.delimiter(),
contents: token_with_metadata_iter_ext::iter_tokens_add_specific_metadata(value.stream(), g, i, p, l).collect(),
span: value.span(),
metadata: g.clone(),
}
}
}
#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
pub struct TokenWithMetadata<T, U> {
pub token: T,
pub metadata: U,
}
impl<T, U> Deref for TokenWithMetadata<T, U> {
type Target = T;
#[inline(always)]
fn deref(&self) -> &Self::Target {
&self.token
}
}
impl<T, U> DerefMut for TokenWithMetadata<T, U> {
#[inline(always)]
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.token
}
}
impl<T, U: Default> From<T> for TokenWithMetadata<T, U> {
#[inline(always)]
fn from(token: T) -> Self {
Self { token, metadata: U::default() }
}
}
impl<T, U> From<(T, U)> for TokenWithMetadata<T, U> {
#[inline(always)]
fn from((token, metadata): (T, U)) -> Self {
Self { token, metadata }
}
}
#[derive(Clone, Debug)]
pub enum TokenTreeWithMetadata<G, I = G, P = G, L = I> {
Group(GroupWithMetadata<G, I, P, L>),
Ident(TokenWithMetadata<Ident, I>),
Punct(TokenWithMetadata<Punct, P>),
Literal(TokenWithMetadata<Literal, L>),
}
impl<G, I, P, L> TokenTreeWithMetadata<G, I, P, L> {
#[inline]
#[must_use = "If you meant to drop this value, use `std::mem::drop` instead."]
pub fn strip_metadata(self) -> TokenTree {
match self {
| TokenTreeWithMetadata::Group(group) => TokenTree::Group(group.strip_metadata()),
| TokenTreeWithMetadata::Ident(twm) => TokenTree::Ident(twm.token),
| TokenTreeWithMetadata::Punct(twm) => TokenTree::Punct(twm.token),
| TokenTreeWithMetadata::Literal(twm) => TokenTree::Literal(twm.token),
}
}
#[inline]
#[must_use]
pub fn span(&self) -> Span {
match self {
| TokenTreeWithMetadata::Group(group) => group.span,
| TokenTreeWithMetadata::Ident(twm) => twm.token.span(),
| TokenTreeWithMetadata::Punct(twm) => twm.token.span(),
| TokenTreeWithMetadata::Literal(twm) => twm.token.span(),
}
}
#[inline]
pub fn set_span(&mut self, span: Span) {
match self {
| TokenTreeWithMetadata::Group(group) => group.span = span,
| TokenTreeWithMetadata::Ident(twm) => twm.token.set_span(span),
| TokenTreeWithMetadata::Punct(twm) => twm.token.set_span(span),
| TokenTreeWithMetadata::Literal(twm) => twm.token.set_span(span),
}
}
}
impl<T> TokenTreeWithMetadata<T> {
#[inline]
#[must_use = "If you meant to drop this value, use `std::mem::drop` instead."]
pub fn get_metadata(self) -> T {
match self {
| Self::Group(group) => group.metadata,
| Self::Ident(twm) => twm.metadata,
| Self::Punct(twm) => twm.metadata,
| Self::Literal(twm) => twm.metadata,
}
}
#[inline]
#[must_use]
pub fn get_metadata_ref(&self) -> &T {
match self {
| Self::Group(group) => &group.metadata,
| Self::Ident(twm) => &twm.metadata,
| Self::Punct(twm) => &twm.metadata,
| Self::Literal(twm) => &twm.metadata,
}
}
#[inline]
#[must_use]
pub fn get_metadata_mut(&mut self) -> &mut T {
match self {
| Self::Group(group) => &mut group.metadata,
| Self::Ident(twm) => &mut twm.metadata,
| Self::Punct(twm) => &mut twm.metadata,
| Self::Literal(twm) => &mut twm.metadata,
}
}
#[inline]
pub fn set_metadata(&mut self, metadata: T) {
match self {
| Self::Group(group) => group.metadata = metadata,
| Self::Ident(twm) => twm.metadata = metadata,
| Self::Punct(twm) => twm.metadata = metadata,
| Self::Literal(twm) => twm.metadata = metadata,
}
}
}
impl<G, I, P, L> From<TokenTree> for TokenTreeWithMetadata<G, I, P, L>
where
G: Default,
I: Default,
P: Default,
L: Default,
{
#[inline]
fn from(tree: TokenTree) -> Self {
match tree {
| TokenTree::Group(group) => Self::Group(group.into()),
| TokenTree::Ident(ident) => Self::Ident(ident.into()),
| TokenTree::Punct(punct) => Self::Punct(punct.into()),
| TokenTree::Literal(literal) => Self::Literal(literal.into()),
}
}
}
impl<T> From<(TokenTree, &T)> for TokenTreeWithMetadata<T>
where
T: Clone,
{
#[inline]
fn from((tree, metadata): (TokenTree, &T)) -> Self {
match tree {
| TokenTree::Group(group) => Self::Group((group, metadata).into()),
| TokenTree::Ident(ident) => Self::Ident((ident, metadata.clone()).into()),
| TokenTree::Punct(punct) => Self::Punct((punct, metadata.clone()).into()),
| TokenTree::Literal(literal) => Self::Literal((literal, metadata.clone()).into()),
}
}
}
impl<G, I, P, L> From<(TokenTree, &G, &I, &P, &L)> for TokenTreeWithMetadata<G, I, P, L>
where
G: Clone,
I: Clone,
P: Clone,
L: Clone,
{
#[inline]
fn from((tree, g, i, p, l): (TokenTree, &G, &I, &P, &L)) -> Self {
match tree {
| TokenTree::Group(group) => Self::Group((group, g, i, p, l).into()),
| TokenTree::Ident(ident) => Self::Ident((ident, i.clone()).into()),
| TokenTree::Punct(punct) => Self::Punct((punct, p.clone()).into()),
| TokenTree::Literal(literal) => Self::Literal((literal, l.clone()).into()),
}
}
}
impl<G, I, P, L> From<Group> for TokenTreeWithMetadata<G, I, P, L>
where
G: Default,
I: Default,
P: Default,
L: Default,
{
#[inline(always)]
fn from(group: Group) -> Self {
Self::Group(group.into())
}
}
impl<T> From<(Group, &T)> for TokenTreeWithMetadata<T>
where
T: Clone,
{
#[inline(always)]
fn from(group_and_val: (Group, &T)) -> Self {
Self::Group(group_and_val.into())
}
}
impl<G, I, P, L> From<(Group, &G, &I, &P, &L)> for TokenTreeWithMetadata<G, I, P, L>
where
G: Clone,
I: Clone,
P: Clone,
L: Clone,
{
#[inline(always)]
fn from(group_and_vals: (Group, &G, &I, &P, &L)) -> Self {
Self::Group(group_and_vals.into())
}
}
impl<G, I, P, L> From<Ident> for TokenTreeWithMetadata<G, I, P, L>
where
I: Default,
{
#[inline(always)]
fn from(ident: Ident) -> Self {
Self::Ident(ident.into())
}
}
impl<G, I, P, L> From<(Ident, I)> for TokenTreeWithMetadata<G, I, P, L> {
#[inline(always)]
fn from((ident, metadata): (Ident, I)) -> Self {
Self::Ident((ident, metadata).into())
}
}
impl<G, I, P, L> From<Punct> for TokenTreeWithMetadata<G, I, P, L>
where
P: Default,
{
#[inline(always)]
fn from(punct: Punct) -> Self {
Self::Punct(punct.into())
}
}
impl<G, I, P, L> From<(Punct, P)> for TokenTreeWithMetadata<G, I, P, L> {
#[inline(always)]
fn from((punct, metadata): (Punct, P)) -> Self {
Self::Punct((punct, metadata).into())
}
}
impl<G, I, P, L> From<Literal> for TokenTreeWithMetadata<G, I, P, L>
where
L: Default,
{
#[inline(always)]
fn from(literal: Literal) -> Self {
Self::Literal(literal.into())
}
}
impl<G, I, P, L> From<(Literal, L)> for TokenTreeWithMetadata<G, I, P, L> {
#[inline(always)]
fn from((literal, metadata): (Literal, L)) -> Self {
Self::Literal((literal, metadata).into())
}
}
pub type TokenWithMetadataVec<G, I = G, P = G, L = I> = Vec<TokenTreeWithMetadata<G, I, P, L>>;
pub mod token_with_metadata_iter_ext {
use super::*;
pub fn iter_tokens_strip_metadata<G, I, P, L>(iter: impl IntoIterator<Item = TokenTreeWithMetadata<G, I, P, L>>) -> impl Iterator<Item = TokenTree> {
iter.into_iter().map(|ttwm| ttwm.strip_metadata())
}
pub fn iter_tokens_add_default_metadata<G, I, P, L>(iter: impl IntoIterator<Item = TokenTree>) -> impl Iterator<Item = TokenTreeWithMetadata<G, I, P, L>>
where
G: Default,
I: Default,
P: Default,
L: Default,
{
iter.into_iter().map(|tt| tt.into())
}
pub fn iter_tokens_add_metadata<T>(iter: impl IntoIterator<Item = TokenTree>, metadata: &T) -> impl Iterator<Item = TokenTreeWithMetadata<T>>
where
T: Clone,
{
iter.into_iter().map(move |tt| (tt, metadata).into())
}
pub fn iter_tokens_add_specific_metadata<G, I, P, L>(
iter: impl IntoIterator<Item = TokenTree>,
group: &G,
ident: &I,
punct: &P,
literal: &L,
) -> impl Iterator<Item = TokenTreeWithMetadata<G, I, P, L>>
where
G: Clone,
I: Clone,
P: Clone,
L: Clone,
{
iter.into_iter().map(move |tt| (tt, group, ident, punct, literal).into())
}
}