1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
#![cfg_attr(all(doc, not(doctest)), feature(doc_auto_cfg))]
#![doc = include_str!("../README.md")]
#![warn(missing_docs)]

#[cfg(feature = "proc-macro")]
extern crate proc_macro;

pub mod prelude {
    //! The prelude imports all the crate's traits with `use ... as _`.
    pub use crate::AsTokenBuf as _;
    pub use crate::AsTokenBufMut as _;
    pub use crate::DefaultParser as _;
    pub use crate::Delimiter as _;
    pub use crate::DelimiterExt as _;
    pub use crate::Group as _;
    pub use crate::GroupExt as _;
    pub use crate::Ident as _;
    pub use crate::IdentExt as _;
    pub use crate::Literal as _;
    pub use crate::LiteralExt as _;
    pub use crate::Parse as _;
    pub use crate::Parser as _;
    pub use crate::ProcMacro as _;
    pub use crate::ProcMacroExt as _;
    pub use crate::Punct as _;
    pub use crate::PunctExt as _;
    pub use crate::Spacing as _;
    pub use crate::SpacingExt as _;
    pub use crate::Span as _;
    pub use crate::SpanExt as _;
    pub use crate::ToTokenBuffer as _;
    pub use crate::ToTokenStream as _;
    pub use crate::ToTokens as _;
    pub use crate::TokenStream as _;
    pub use crate::TokenStreamExt as _;
    pub use crate::TokenTree as _;
    pub use crate::TokenTreeExt as _;
}

mod base;
mod error;
mod literal;
mod op;
mod punctuated;
mod span;
mod token;
mod token_buffer;
mod token_stream;
mod token_tree;

#[cfg(feature = "proc-macro")]
pub use base::PM1;
#[cfg(feature = "proc-macro2")]
pub use base::PM2;
pub use base::{PMExt, ProcMacro, ProcMacroExt, PM};
pub use error::Error;
#[cfg(feature = "literal-value")]
pub use literal::{
    ByteCharacterLiteral, ByteStringLiteral, CStringLiteral, CharacterLiteral, F32Literal,
    F64Literal, FloatLiteral, I128Literal, I16Literal, I32Literal, I64Literal, I8Literal,
    IntLiteral, IsizeLiteral, LiteralValue, StringLiteral, U128Literal, U16Literal, U32Literal,
    U64Literal, U8Literal, UsizeLiteral,
};
pub use literal::{Literal, LiteralExt};
pub use op::{op, MatchOpFn, Op, OpParser, OpParserInstance, Puncts};
pub use punctuated::{punctuated, Punctuated, PunctuatedParser};
pub use span::{Span, SpanExt};
pub use token::{IntoTokens, ToTokenStream, ToTokens};
pub use token_buffer::{
    AsTokenBuf, AsTokenBufMut, DefaultParser, Optional, Parse, Parser, ToTokenBuffer, TokenBuf,
    TokenBuffer,
};
pub use token_stream::{TokenStream, TokenStreamExt};
pub use token_tree::{
    Delimiter, DelimiterExt, DelimiterKind, Group, GroupExt, Ident, IdentExt, Punct, PunctExt,
    Spacing, SpacingExt, TokenTree, TokenTreeExt, TokenTreeKind,
};

/// Optional wrapper for proc macros.
pub fn proclet<T: TokenStreamExt, U: ToTokenStream<T>>(
    input: impl Into<TokenBuffer<T::TokenTree>>,
    f: impl FnOnce(&mut &TokenBuf<T::TokenTree>) -> Result<U, Error<T::Span>>,
) -> T {
    let buffer = input.into();
    match f(&mut buffer.as_buf()) {
        Ok(out) => out.into_token_stream(),
        Err(e) => e.to_compile_error(),
    }
}

/// Match results.
pub enum Match<T> {
    /// The match is complete; stop looking.
    Complete(T),

    /// A match was found, but there may be a longer match; keep looking.
    Partial(T),

    /// More data is needed to find a match.
    NeedMore,

    /// There's no more matches to be found. Stop looking.
    NoMatch,
}

macro_rules! pm {
    ($($mod:ident: $pm:ident: $feature:literal),*) => { $(
        #[cfg(feature = $feature)]
        #[doc = concat!("Type aliases for use with ", $feature, ".")]
        pub mod $mod {
            pub use crate::{Punctuated, Optional};
            use $pm::*;
            pm! {
                @ $feature;
                Error = Error<Span>;
                PunctuatedParser<M, D> = PunctuatedParser<TokenTree, M, D>;
                "literal-value" LiteralValue = LiteralValue<Span>;
                "literal-value" StringLiteral = StringLiteral<Span>;
                "literal-value" ByteStringLiteral = ByteStringLiteral<Span>;
                "literal-value" CStringLiteral = CStringLiteral<Span>;
                "literal-value" CharacterLiteral = CharacterLiteral<Span>;
                "literal-value" ByteCharacterLiteral = ByteCharacterLiteral<Span>;
                "literal-value" IntLiteral = IntLiteral<Span>;
                "literal-value" FloatLiteral = FloatLiteral<Span>;
                "literal-value" I8Literal = I8Literal<Span>;
                "literal-value" I16Literal = I16Literal<Span>;
                "literal-value" I32Literal = I32Literal<Span>;
                "literal-value" I64Literal = I64Literal<Span>;
                "literal-value" I128Literal = I128Literal<Span>;
                "literal-value" IsizeLiteral = IsizeLiteral<Span>;
                "literal-value" U8Literal = U8Literal<Span>;
                "literal-value" U16Literal = U16Literal<Span>;
                "literal-value" U32Literal = U32Literal<Span>;
                "literal-value" U64Literal = U64Literal<Span>;
                "literal-value" U128Literal = U128Literal<Span>;
                "literal-value" UsizeLiteral = UsizeLiteral<Span>;
                "literal-value" F32Literal = F32Literal<Span>;
                "literal-value" F64Literal = F64Literal<Span>;
                Op = Op<Span>;
                OpParser<F> = OpParser<Punct, F>;
                OpParserInstance<F> = OpParserInstance<Punct, F>;
                Puncts<'a> = Puncts<'a, Punct>;
                TokenBuffer = TokenBuffer<TokenTree>;
                TokenBuf = TokenBuf<TokenTree>;
            }
        }
    )* };

    (@ $pm:literal; $($($feat:literal)? $alias:ident $(<$($gl:lifetime),* $(,)? $($g:ident),*>)? = $t:ident$(<$($tgl:lifetime),* $(,)? $($tg:ident),*>)?;)*) => { $(
        $( #[cfg(feature = $feat)] )?
        #[doc = concat!("`", stringify!($alias), "` for ", $pm, ".")]
        pub type $alias $(<$($gl,)* $($g),*>)? = crate::$t$(<$($tgl,)* $($tg),*>)?;
    )* };
}

pm!(pm1: proc_macro: "proc-macro", pm2: proc_macro2: "proc-macro2");

use internal::*;
mod internal {
    use std::{fmt::Debug, str::FromStr};

    pub trait Sealed {}

    pub trait FromStrDebug: FromStr<Err = Self::ErrDbg> {
        type ErrDbg: Debug;
    }
    impl<T: FromStr<Err = E>, E: Debug> FromStrDebug for T {
        type ErrDbg = E;
    }
}