Skip to main content

moxy_token/
lib.rs

1#![cfg_attr(nightly, feature(proc_macro_diagnostic, proc_macro_span, proc_macro_def_site,))]
2
3//! # Moxy tokens
4//!
5//! Token types, lexing, spans, and compiler-token conversions for Rust syntax
6//! tooling. [`TokenStream`] is an owned sequence of [`TokenTree`] values that
7//! preserves token text, punctuation spacing, and source spans.
8//!
9//! ## Quick start
10//!
11//! Parse source into a token stream, or construct individual token types with
12//! the provided macros:
13//!
14//! ```ignore
15//! use moxy::token::{ident, TokenStream};
16//! use moxy::Token;
17//!
18//! let stream: TokenStream = "fn generated() {}".parse().unwrap();
19//! let name = ident!(generated);
20//! let semi: Token![;] = Default::default();
21//! assert_eq!(name.to_string(), "generated");
22//! assert_eq!(semi.to_string(), ";");
23//! ```
24//!
25//! ## Integrations
26//!
27//! Enable `serde` to serialize supported token types. Enable `proc-macro2` for
28//! conversions with `proc_macro2`; compiler `proc_macro` conversions are
29//! available through [`bridge`].
30
31extern crate proc_macro;
32
33/// Conversions to and from compiler token-stream representations.
34pub mod bridge;
35mod delim;
36mod group;
37mod ident;
38/// Rust keyword token types.
39pub mod keyword;
40/// Lexing primitives and lexical errors.
41pub mod lex;
42pub mod lit;
43/// Rust punctuation token types.
44pub mod punct;
45/// Source files, locations, and source maps used by spans.
46pub mod source;
47mod spacing;
48/// Source-span types and the [`Spanner`] trait.
49pub mod span;
50mod stream;
51mod tree;
52
53#[doc(inline)]
54pub use delim::*;
55#[doc(inline)]
56pub use group::*;
57#[doc(inline)]
58pub use ident::*;
59#[doc(inline)]
60pub use keyword::*;
61#[doc(inline)]
62pub use lex::{LexError, Scan};
63#[doc(inline)]
64pub use lit::*;
65#[doc(inline)]
66pub use punct::*;
67#[doc(inline)]
68pub use spacing::*;
69#[doc(inline)]
70pub use span::{Span, Spanner};
71#[doc(inline)]
72pub use stream::*;
73#[doc(inline)]
74pub use tree::*;
75
76/// Emits a value as tokens into a destination token stream.
77/// A public Rust token API type for to tokens<t.
78pub trait ToTokens<T = TokenStream> {
79    fn to_tokens(&self, tokens: &mut T);
80}
81
82/// Convenience methods for values that can emit a [`TokenStream`].
83/// A public Rust token API type for to token stream:.
84pub trait ToTokenStream: ToTokens<TokenStream> {
85    fn to_token_stream(&self) -> TokenStream {
86        let mut tokens = TokenStream::new();
87        self.to_tokens(&mut tokens);
88        tokens
89    }
90
91    fn into_token_stream(self) -> TokenStream
92    where
93        Self: Sized,
94    {
95        self.to_token_stream()
96    }
97}
98
99impl<X: ToTokens<TokenStream> + ?Sized> ToTokenStream for X {}
100
101impl<T: ToTokens> ToTokens for ::std::boxed::Box<T> {
102    fn to_tokens(&self, tokens: &mut TokenStream) {
103        (**self).to_tokens(tokens);
104    }
105}
106
107impl<T: ToTokens> ToTokens for &T {
108    fn to_tokens(&self, tokens: &mut TokenStream) {
109        ToTokens::to_tokens(*self, tokens);
110    }
111}
112
113impl<T: ToTokens> ToTokens for Option<T> {
114    fn to_tokens(&self, tokens: &mut TokenStream) {
115        if let Some(v) = self {
116            v.to_tokens(tokens);
117        }
118    }
119}
120
121impl<T: ToTokens> ToTokens for Vec<T> {
122    fn to_tokens(&self, tokens: &mut TokenStream) {
123        for v in self {
124            v.to_tokens(tokens);
125        }
126    }
127}
128
129impl<T: ToTokens, E: ToTokens> ToTokens for Result<T, E> {
130    fn to_tokens(&self, tokens: &mut TokenStream) {
131        match self {
132            Self::Ok(v) => v.to_tokens(tokens),
133            Self::Err(err) => err.to_tokens(tokens),
134        }
135    }
136}
137
138/// Map a Rust punctuation or keyword symbol to its [`crate`] token type.
139#[macro_export]
140macro_rules! Token {
141    // --- punctuation: single char ---
142    [&]     => { $crate::And };
143    [|]     => { $crate::Or };
144    [!]     => { $crate::Not };
145    [~]     => { $crate::Tilde };
146    [+]     => { $crate::Plus };
147    [-]     => { $crate::Minus };
148    [_]     => { $crate::Underscore };
149    [*]     => { $crate::Star };
150    [/]     => { $crate::Slash };
151    [%]     => { $crate::Percent };
152    [^]     => { $crate::Caret };
153    [=]     => { $crate::Eq };
154    [<]     => { $crate::Lt };
155    [>]     => { $crate::Gt };
156    [@]     => { $crate::At };
157    [.]     => { $crate::Dot };
158    [,]     => { $crate::Comma };
159    [;]     => { $crate::Semi };
160    [:]     => { $crate::Colon };
161    [#]     => { $crate::Pound };
162    [$]     => { $crate::Dollar };
163    [?]     => { $crate::Question };
164
165    // --- keywords ---
166    [as]          => { $crate::As };
167    [async]       => { $crate::Async };
168    [auto]        => { $crate::Auto };
169    [await]       => { $crate::Await };
170    [become]      => { $crate::Become };
171    [box]         => { $crate::Box };
172    [break]       => { $crate::Break };
173    [const]       => { $crate::Const };
174    [continue]    => { $crate::Continue };
175    [crate]       => { $crate::Crate };
176    [default]     => { $crate::Default };
177    [do]          => { $crate::Do };
178    [dyn]         => { $crate::Dyn };
179    [else]        => { $crate::Else };
180    [enum]        => { $crate::Enum };
181    [extern]      => { $crate::Extern };
182    [final]       => { $crate::Final };
183    [fn]          => { $crate::Fn };
184    [for]         => { $crate::For };
185    [if]          => { $crate::If };
186    [impl]        => { $crate::Impl };
187    [in]          => { $crate::In };
188    [let]         => { $crate::Let };
189    [loop]        => { $crate::Loop };
190    [macro]       => { $crate::Macro };
191    [macro_rules] => { $crate::MacroRules };
192    [match]       => { $crate::Match };
193    [mod]         => { $crate::Mod };
194    [move]        => { $crate::Move };
195    [mut]         => { $crate::Mut };
196    [override]    => { $crate::Override };
197    [priv]        => { $crate::Priv };
198    [pub]         => { $crate::Pub };
199    [raw]         => { $crate::Raw };
200    [ref]         => { $crate::Ref };
201    [return]      => { $crate::Return };
202    [Self]        => { $crate::SelfType };
203    [self]        => { $crate::SelfValue };
204    [static]      => { $crate::Static };
205    [struct]      => { $crate::Struct };
206    [super]       => { $crate::Super };
207    [trait]       => { $crate::Trait };
208    [try]         => { $crate::Try };
209    [type]        => { $crate::Type };
210    [typeof]      => { $crate::Typeof };
211    [union]       => { $crate::Union };
212    [unsafe]      => { $crate::Unsafe };
213    [unsized]     => { $crate::Unsized };
214    [use]         => { $crate::Use };
215    [virtual]     => { $crate::Virtual };
216    [where]       => { $crate::Where };
217    [while]       => { $crate::While };
218    [yield]       => { $crate::Yield };
219}