blob: 49010235286e4585cec90177da083a824e914a1d [file] [log] [blame]
Alex Crichton1fd0e8a2018-02-04 21:29:13 -08001//! A "shim crate" intended to multiplex the [`proc_macro`] API on to stable
2//! Rust.
Alex Crichtonbabc99e2017-07-05 18:00:29 -07003//!
4//! Procedural macros in Rust operate over the upstream
Alex Crichton1fd0e8a2018-02-04 21:29:13 -08005//! [`proc_macro::TokenStream`][ts] type. This type currently is quite
6//! conservative and exposed no internal implementation details. Nightly
7//! compilers, however, contain a much richer interface. This richer interface
8//! allows fine-grained inspection of the token stream which avoids
9//! stringification/re-lexing and also preserves span information.
Alex Crichtonbabc99e2017-07-05 18:00:29 -070010//!
Alex Crichton1fd0e8a2018-02-04 21:29:13 -080011//! The upcoming APIs added to [`proc_macro`] upstream are the foundation for
Alex Crichtonbabc99e2017-07-05 18:00:29 -070012//! productive procedural macros in the ecosystem. To help prepare the ecosystem
13//! for using them this crate serves to both compile on stable and nightly and
14//! mirrors the API-to-be. The intention is that procedural macros which switch
15//! to use this crate will be trivially able to switch to the upstream
16//! `proc_macro` crate once its API stabilizes.
17//!
David Tolnayd66ecf62018-01-02 20:05:42 -080018//! In the meantime this crate also has a `nightly` Cargo feature which
Alex Crichton1fd0e8a2018-02-04 21:29:13 -080019//! enables it to reimplement itself with the unstable API of [`proc_macro`].
Alex Crichtonbabc99e2017-07-05 18:00:29 -070020//! This'll allow immediate usage of the beneficial upstream API, particularly
21//! around preserving span information.
Alex Crichton1fd0e8a2018-02-04 21:29:13 -080022//!
23//! [`proc_macro`]: https://doc.rust-lang.org/proc_macro/
24//! [ts]: https://doc.rust-lang.org/proc_macro/struct.TokenStream.html
Alex Crichtonbabc99e2017-07-05 18:00:29 -070025
David Tolnay15cc4982018-01-08 08:03:27 -080026// Proc-macro2 types in rustdoc of other crates get linked to here.
David Tolnay2c1dac52018-04-23 19:18:07 -070027#![doc(html_root_url = "https://docs.rs/proc-macro2/0.3.7")]
David Tolnayd66ecf62018-01-02 20:05:42 -080028#![cfg_attr(feature = "nightly", feature(proc_macro))]
Alex Crichtoncbec8ec2017-06-02 13:19:33 -070029
Alex Crichton0e8e7f42018-02-22 06:15:13 -080030#[cfg(feature = "proc-macro")]
Alex Crichton44bffbc2017-05-19 17:51:59 -070031extern crate proc_macro;
32
David Tolnayd66ecf62018-01-02 20:05:42 -080033#[cfg(not(feature = "nightly"))]
David Tolnayb1032662017-05-31 15:52:28 -070034extern crate unicode_xid;
Alex Crichton44bffbc2017-05-19 17:51:59 -070035
36use std::fmt;
Alex Crichton44bffbc2017-05-19 17:51:59 -070037use std::iter::FromIterator;
Alex Crichtonaf5bad42018-03-27 14:45:10 -070038use std::marker;
39use std::rc::Rc;
40use std::str::FromStr;
Alex Crichton44bffbc2017-05-19 17:51:59 -070041
David Tolnayb1032662017-05-31 15:52:28 -070042#[macro_use]
David Tolnayd66ecf62018-01-02 20:05:42 -080043#[cfg(not(feature = "nightly"))]
David Tolnayb1032662017-05-31 15:52:28 -070044mod strnom;
45
Alex Crichton44bffbc2017-05-19 17:51:59 -070046#[path = "stable.rs"]
David Tolnayd66ecf62018-01-02 20:05:42 -080047#[cfg(not(feature = "nightly"))]
Alex Crichtonb15c6352017-05-19 19:36:36 -070048mod imp;
49#[path = "unstable.rs"]
David Tolnayd66ecf62018-01-02 20:05:42 -080050#[cfg(feature = "nightly")]
Alex Crichton44bffbc2017-05-19 17:51:59 -070051mod imp;
52
David Tolnaycb1b85f2017-06-03 16:40:35 -070053#[derive(Clone)]
Alex Crichtonaf5bad42018-03-27 14:45:10 -070054pub struct TokenStream {
55 inner: imp::TokenStream,
56 _marker: marker::PhantomData<Rc<()>>,
57}
Alex Crichton44bffbc2017-05-19 17:51:59 -070058
Alex Crichtonaf5bad42018-03-27 14:45:10 -070059pub struct LexError {
60 inner: imp::LexError,
61 _marker: marker::PhantomData<Rc<()>>,
62}
63
64impl TokenStream {
65 fn _new(inner: imp::TokenStream) -> TokenStream {
66 TokenStream {
67 inner: inner,
68 _marker: marker::PhantomData,
69 }
70 }
71
72 pub fn empty() -> TokenStream {
73 TokenStream::_new(imp::TokenStream::empty())
74 }
75
76 pub fn is_empty(&self) -> bool {
77 self.inner.is_empty()
78 }
79}
Alex Crichton44bffbc2017-05-19 17:51:59 -070080
81impl FromStr for TokenStream {
82 type Err = LexError;
83
84 fn from_str(src: &str) -> Result<TokenStream, LexError> {
David Tolnayb28f38a2018-03-31 22:02:29 +020085 let e = src.parse().map_err(|e| LexError {
86 inner: e,
87 _marker: marker::PhantomData,
Alex Crichtonaf5bad42018-03-27 14:45:10 -070088 })?;
89 Ok(TokenStream::_new(e))
Alex Crichton44bffbc2017-05-19 17:51:59 -070090 }
91}
92
Alex Crichton0e8e7f42018-02-22 06:15:13 -080093#[cfg(feature = "proc-macro")]
Alex Crichton44bffbc2017-05-19 17:51:59 -070094impl From<proc_macro::TokenStream> for TokenStream {
95 fn from(inner: proc_macro::TokenStream) -> TokenStream {
Alex Crichtonaf5bad42018-03-27 14:45:10 -070096 TokenStream::_new(inner.into())
Alex Crichton44bffbc2017-05-19 17:51:59 -070097 }
98}
99
Alex Crichton0e8e7f42018-02-22 06:15:13 -0800100#[cfg(feature = "proc-macro")]
Alex Crichton44bffbc2017-05-19 17:51:59 -0700101impl From<TokenStream> for proc_macro::TokenStream {
102 fn from(inner: TokenStream) -> proc_macro::TokenStream {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700103 inner.inner.into()
Alex Crichton44bffbc2017-05-19 17:51:59 -0700104 }
105}
106
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700107impl FromIterator<TokenTree> for TokenStream {
108 fn from_iter<I: IntoIterator<Item = TokenTree>>(streams: I) -> Self {
109 TokenStream::_new(streams.into_iter().collect())
Alex Crichton44bffbc2017-05-19 17:51:59 -0700110 }
111}
112
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700113impl fmt::Display for TokenStream {
114 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
115 self.inner.fmt(f)
Alex Crichton44bffbc2017-05-19 17:51:59 -0700116 }
117}
118
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700119impl fmt::Debug for TokenStream {
120 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
121 self.inner.fmt(f)
Alex Crichton44bffbc2017-05-19 17:51:59 -0700122 }
123}
124
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700125impl fmt::Debug for LexError {
126 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
127 self.inner.fmt(f)
Alex Crichton44bffbc2017-05-19 17:51:59 -0700128 }
129}
130
Nika Layzellb35a9a32017-12-30 14:34:35 -0500131// Returned by reference, so we can't easily wrap it.
David Tolnay1ebe3972018-01-02 20:14:20 -0800132#[cfg(procmacro2_semver_exempt)]
Nika Layzellb35a9a32017-12-30 14:34:35 -0500133pub use imp::FileName;
134
David Tolnay1ebe3972018-01-02 20:14:20 -0800135#[cfg(procmacro2_semver_exempt)]
Nika Layzellf8d5f212017-12-11 14:07:02 -0500136#[derive(Clone, PartialEq, Eq)]
137pub struct SourceFile(imp::SourceFile);
138
David Tolnay1ebe3972018-01-02 20:14:20 -0800139#[cfg(procmacro2_semver_exempt)]
Nika Layzellf8d5f212017-12-11 14:07:02 -0500140impl SourceFile {
141 /// Get the path to this source file as a string.
Nika Layzellb35a9a32017-12-30 14:34:35 -0500142 pub fn path(&self) -> &FileName {
143 self.0.path()
Nika Layzellf8d5f212017-12-11 14:07:02 -0500144 }
145
146 pub fn is_real(&self) -> bool {
147 self.0.is_real()
148 }
149}
150
David Tolnay1ebe3972018-01-02 20:14:20 -0800151#[cfg(procmacro2_semver_exempt)]
Nika Layzellb35a9a32017-12-30 14:34:35 -0500152impl AsRef<FileName> for SourceFile {
153 fn as_ref(&self) -> &FileName {
154 self.0.path()
Nika Layzellf8d5f212017-12-11 14:07:02 -0500155 }
156}
157
David Tolnay1ebe3972018-01-02 20:14:20 -0800158#[cfg(procmacro2_semver_exempt)]
Nika Layzellf8d5f212017-12-11 14:07:02 -0500159impl fmt::Debug for SourceFile {
160 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
161 self.0.fmt(f)
162 }
163}
164
David Tolnay1ebe3972018-01-02 20:14:20 -0800165#[cfg(procmacro2_semver_exempt)]
Nika Layzell1ecb6ce2017-12-30 14:34:05 -0500166pub struct LineColumn {
167 pub line: usize,
168 pub column: usize,
169}
Nika Layzellf8d5f212017-12-11 14:07:02 -0500170
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700171#[derive(Copy, Clone)]
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700172pub struct Span {
173 inner: imp::Span,
174 _marker: marker::PhantomData<Rc<()>>,
175}
Alex Crichton44bffbc2017-05-19 17:51:59 -0700176
Alex Crichton44bffbc2017-05-19 17:51:59 -0700177impl Span {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700178 fn _new(inner: imp::Span) -> Span {
179 Span {
180 inner: inner,
181 _marker: marker::PhantomData,
182 }
Alex Crichton44bffbc2017-05-19 17:51:59 -0700183 }
Alex Crichtone6085b72017-11-21 07:24:25 -0800184
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700185 pub fn call_site() -> Span {
186 Span::_new(imp::Span::call_site())
187 }
188
189 #[cfg(procmacro2_semver_exempt)]
Alex Crichtone6085b72017-11-21 07:24:25 -0800190 pub fn def_site() -> Span {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700191 Span::_new(imp::Span::def_site())
Alex Crichtone6085b72017-11-21 07:24:25 -0800192 }
Nika Layzellf8d5f212017-12-11 14:07:02 -0500193
David Tolnay4e8e3972018-01-05 18:10:22 -0800194 /// Creates a new span with the same line/column information as `self` but
195 /// that resolves symbols as though it were at `other`.
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700196 #[cfg(procmacro2_semver_exempt)]
David Tolnay4e8e3972018-01-05 18:10:22 -0800197 pub fn resolved_at(&self, other: Span) -> Span {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700198 Span::_new(self.inner.resolved_at(other.inner))
David Tolnay4e8e3972018-01-05 18:10:22 -0800199 }
200
201 /// Creates a new span with the same name resolution behavior as `self` but
202 /// with the line/column information of `other`.
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700203 #[cfg(procmacro2_semver_exempt)]
David Tolnay4e8e3972018-01-05 18:10:22 -0800204 pub fn located_at(&self, other: Span) -> Span {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700205 Span::_new(self.inner.located_at(other.inner))
David Tolnay4e8e3972018-01-05 18:10:22 -0800206 }
207
David Tolnayd66ecf62018-01-02 20:05:42 -0800208 /// This method is only available when the `"nightly"` feature is enabled.
Alex Crichton0e8e7f42018-02-22 06:15:13 -0800209 #[cfg(all(feature = "nightly", feature = "proc-macro"))]
David Tolnay16a17202017-12-31 10:47:24 -0500210 pub fn unstable(self) -> proc_macro::Span {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700211 self.inner.unstable()
David Tolnay16a17202017-12-31 10:47:24 -0500212 }
213
David Tolnay1ebe3972018-01-02 20:14:20 -0800214 #[cfg(procmacro2_semver_exempt)]
Nika Layzellf8d5f212017-12-11 14:07:02 -0500215 pub fn source_file(&self) -> SourceFile {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700216 SourceFile(self.inner.source_file())
Nika Layzellf8d5f212017-12-11 14:07:02 -0500217 }
218
David Tolnay1ebe3972018-01-02 20:14:20 -0800219 #[cfg(procmacro2_semver_exempt)]
Nika Layzellf8d5f212017-12-11 14:07:02 -0500220 pub fn start(&self) -> LineColumn {
David Tolnayb28f38a2018-03-31 22:02:29 +0200221 let imp::LineColumn { line, column } = self.inner.start();
222 LineColumn {
223 line: line,
224 column: column,
225 }
Nika Layzellf8d5f212017-12-11 14:07:02 -0500226 }
227
David Tolnay1ebe3972018-01-02 20:14:20 -0800228 #[cfg(procmacro2_semver_exempt)]
Nika Layzellf8d5f212017-12-11 14:07:02 -0500229 pub fn end(&self) -> LineColumn {
David Tolnayb28f38a2018-03-31 22:02:29 +0200230 let imp::LineColumn { line, column } = self.inner.end();
231 LineColumn {
232 line: line,
233 column: column,
234 }
Nika Layzellf8d5f212017-12-11 14:07:02 -0500235 }
236
David Tolnay1ebe3972018-01-02 20:14:20 -0800237 #[cfg(procmacro2_semver_exempt)]
Nika Layzellf8d5f212017-12-11 14:07:02 -0500238 pub fn join(&self, other: Span) -> Option<Span> {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700239 self.inner.join(other.inner).map(Span::_new)
240 }
Alex Crichtonb2c94622018-04-04 07:36:41 -0700241
242 #[cfg(procmacro2_semver_exempt)]
243 pub fn eq(&self, other: &Span) -> bool {
244 self.inner.eq(&other.inner)
245 }
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700246}
247
248impl fmt::Debug for Span {
249 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
250 self.inner.fmt(f)
Nika Layzellf8d5f212017-12-11 14:07:02 -0500251 }
Alex Crichton44bffbc2017-05-19 17:51:59 -0700252}
253
David Tolnay034205f2018-04-22 16:45:28 -0700254#[derive(Clone)]
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700255pub enum TokenTree {
256 Group(Group),
257 Term(Term),
258 Op(Op),
259 Literal(Literal),
Alex Crichton1a7f7622017-07-05 17:47:15 -0700260}
261
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700262impl TokenTree {
263 pub fn span(&self) -> Span {
264 match *self {
265 TokenTree::Group(ref t) => t.span(),
266 TokenTree::Term(ref t) => t.span(),
267 TokenTree::Op(ref t) => t.span(),
268 TokenTree::Literal(ref t) => t.span(),
269 }
270 }
271
272 pub fn set_span(&mut self, span: Span) {
273 match *self {
274 TokenTree::Group(ref mut t) => t.set_span(span),
275 TokenTree::Term(ref mut t) => t.set_span(span),
276 TokenTree::Op(ref mut t) => t.set_span(span),
277 TokenTree::Literal(ref mut t) => t.set_span(span),
278 }
279 }
280}
281
282impl From<Group> for TokenTree {
283 fn from(g: Group) -> TokenTree {
284 TokenTree::Group(g)
285 }
286}
287
288impl From<Term> for TokenTree {
289 fn from(g: Term) -> TokenTree {
290 TokenTree::Term(g)
291 }
292}
293
294impl From<Op> for TokenTree {
295 fn from(g: Op) -> TokenTree {
296 TokenTree::Op(g)
297 }
298}
299
300impl From<Literal> for TokenTree {
301 fn from(g: Literal) -> TokenTree {
302 TokenTree::Literal(g)
Alex Crichton1a7f7622017-07-05 17:47:15 -0700303 }
Alex Crichton44bffbc2017-05-19 17:51:59 -0700304}
305
Alex Crichton44bffbc2017-05-19 17:51:59 -0700306impl fmt::Display for TokenTree {
307 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700308 match *self {
309 TokenTree::Group(ref t) => t.fmt(f),
310 TokenTree::Term(ref t) => t.fmt(f),
311 TokenTree::Op(ref t) => t.fmt(f),
312 TokenTree::Literal(ref t) => t.fmt(f),
313 }
Alex Crichton44bffbc2017-05-19 17:51:59 -0700314 }
315}
316
David Tolnay034205f2018-04-22 16:45:28 -0700317impl fmt::Debug for TokenTree {
318 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
319 // Each of these has the name in the struct type in the derived debug,
320 // so don't bother with an extra layer of indirection
321 match *self {
322 TokenTree::Group(ref t) => t.fmt(f),
323 TokenTree::Term(ref t) => t.fmt(f),
324 TokenTree::Op(ref t) => t.fmt(f),
325 TokenTree::Literal(ref t) => t.fmt(f),
326 }
327 }
328}
329
330#[derive(Clone)]
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700331pub struct Group {
332 delimiter: Delimiter,
333 stream: TokenStream,
334 span: Span,
Alex Crichton44bffbc2017-05-19 17:51:59 -0700335}
336
Michael Layzell5372f4b2017-06-02 10:29:31 -0400337#[derive(Copy, Clone, Debug, Eq, PartialEq)]
Alex Crichton44bffbc2017-05-19 17:51:59 -0700338pub enum Delimiter {
339 Parenthesis,
340 Brace,
341 Bracket,
342 None,
343}
344
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700345impl Group {
346 pub fn new(delimiter: Delimiter, stream: TokenStream) -> Group {
347 Group {
348 delimiter: delimiter,
349 stream: stream,
350 span: Span::call_site(),
351 }
Alex Crichton44bffbc2017-05-19 17:51:59 -0700352 }
Alex Crichton44bffbc2017-05-19 17:51:59 -0700353
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700354 pub fn delimiter(&self) -> Delimiter {
355 self.delimiter
Alex Crichton44bffbc2017-05-19 17:51:59 -0700356 }
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700357
358 pub fn stream(&self) -> TokenStream {
359 self.stream.clone()
360 }
361
362 pub fn span(&self) -> Span {
363 self.span
364 }
365
366 pub fn set_span(&mut self, span: Span) {
367 self.span = span;
368 }
369}
370
371impl fmt::Display for Group {
372 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
373 self.stream.fmt(f)
374 }
375}
376
David Tolnay034205f2018-04-22 16:45:28 -0700377impl fmt::Debug for Group {
378 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
379 let mut debug = fmt.debug_struct("Group");
380 debug.field("delimiter", &self.delimiter);
381 debug.field("stream", &self.stream);
382 #[cfg(procmacro2_semver_exempt)]
383 debug.field("span", &self.span);
384 debug.finish()
385 }
386}
387
388#[derive(Copy, Clone)]
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700389pub struct Op {
390 op: char,
391 spacing: Spacing,
392 span: Span,
Alex Crichton44bffbc2017-05-19 17:51:59 -0700393}
394
Lukas Kalbertodteb3f9302017-08-20 18:58:41 +0200395#[derive(Copy, Clone, Debug, Eq, PartialEq)]
Alex Crichton1a7f7622017-07-05 17:47:15 -0700396pub enum Spacing {
Alex Crichton44bffbc2017-05-19 17:51:59 -0700397 Alone,
398 Joint,
399}
400
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700401impl Op {
402 pub fn new(op: char, spacing: Spacing) -> Op {
403 Op {
404 op: op,
405 spacing: spacing,
406 span: Span::call_site(),
407 }
408 }
Alex Crichton44bffbc2017-05-19 17:51:59 -0700409
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700410 pub fn op(&self) -> char {
411 self.op
412 }
413
414 pub fn spacing(&self) -> Spacing {
415 self.spacing
416 }
417
418 pub fn span(&self) -> Span {
419 self.span
420 }
421
422 pub fn set_span(&mut self, span: Span) {
423 self.span = span;
424 }
425}
426
427impl fmt::Display for Op {
428 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
429 self.op.fmt(f)
430 }
431}
432
David Tolnay034205f2018-04-22 16:45:28 -0700433impl fmt::Debug for Op {
434 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
435 let mut debug = fmt.debug_struct("Op");
436 debug.field("op", &self.op);
437 debug.field("spacing", &self.spacing);
438 #[cfg(procmacro2_semver_exempt)]
439 debug.field("span", &self.span);
440 debug.finish()
441 }
442}
443
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700444#[derive(Copy, Clone)]
445pub struct Term {
446 inner: imp::Term,
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700447 _marker: marker::PhantomData<Rc<()>>,
448}
449
450impl Term {
Alex Crichtonb2c94622018-04-04 07:36:41 -0700451 fn _new(inner: imp::Term) -> Term {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700452 Term {
453 inner: inner,
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700454 _marker: marker::PhantomData,
455 }
456 }
457
458 pub fn new(string: &str, span: Span) -> Term {
Alex Crichtonb2c94622018-04-04 07:36:41 -0700459 Term::_new(imp::Term::new(string, span.inner))
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700460 }
461
462 pub fn as_str(&self) -> &str {
463 self.inner.as_str()
464 }
465
466 pub fn span(&self) -> Span {
Alex Crichtonb2c94622018-04-04 07:36:41 -0700467 Span::_new(self.inner.span())
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700468 }
469
470 pub fn set_span(&mut self, span: Span) {
Alex Crichtonb2c94622018-04-04 07:36:41 -0700471 self.inner.set_span(span.inner);
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700472 }
473}
474
475impl fmt::Display for Term {
476 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
477 self.as_str().fmt(f)
478 }
479}
480
481impl fmt::Debug for Term {
482 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
483 self.inner.fmt(f)
484 }
485}
486
487#[derive(Clone)]
488pub struct Literal {
489 inner: imp::Literal,
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700490 _marker: marker::PhantomData<Rc<()>>,
491}
492
Alex Crichtona914a612018-04-04 07:48:44 -0700493macro_rules! int_literals {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700494 ($($name:ident => $kind:ident,)*) => ($(
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700495 pub fn $name(n: $kind) -> Literal {
Alex Crichtona914a612018-04-04 07:48:44 -0700496 Literal::_new(imp::Literal::$name(n))
Alex Crichton1a7f7622017-07-05 17:47:15 -0700497 }
498 )*)
499}
500
Alex Crichton852d53d2017-05-19 19:25:08 -0700501impl Literal {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700502 fn _new(inner: imp::Literal) -> Literal {
503 Literal {
504 inner: inner,
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700505 _marker: marker::PhantomData,
506 }
Alex Crichton1a7f7622017-07-05 17:47:15 -0700507 }
508
Alex Crichtona914a612018-04-04 07:48:44 -0700509 int_literals! {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700510 u8_suffixed => u8,
511 u16_suffixed => u16,
512 u32_suffixed => u32,
513 u64_suffixed => u64,
514 usize_suffixed => usize,
515 i8_suffixed => i8,
516 i16_suffixed => i16,
517 i32_suffixed => i32,
518 i64_suffixed => i64,
519 isize_suffixed => isize,
Alex Crichton1a7f7622017-07-05 17:47:15 -0700520
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700521 u8_unsuffixed => u8,
522 u16_unsuffixed => u16,
523 u32_unsuffixed => u32,
524 u64_unsuffixed => u64,
525 usize_unsuffixed => usize,
526 i8_unsuffixed => i8,
527 i16_unsuffixed => i16,
528 i32_unsuffixed => i32,
529 i64_unsuffixed => i64,
530 isize_unsuffixed => isize,
Alex Crichton1a7f7622017-07-05 17:47:15 -0700531 }
532
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700533 pub fn f64_unsuffixed(f: f64) -> Literal {
534 assert!(f.is_finite());
Alex Crichtona914a612018-04-04 07:48:44 -0700535 Literal::_new(imp::Literal::f64_unsuffixed(f))
Alex Crichton1a7f7622017-07-05 17:47:15 -0700536 }
537
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700538 pub fn f64_suffixed(f: f64) -> Literal {
539 assert!(f.is_finite());
Alex Crichtona914a612018-04-04 07:48:44 -0700540 Literal::_new(imp::Literal::f64_suffixed(f))
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700541 }
542
543 pub fn f32_unsuffixed(f: f32) -> Literal {
544 assert!(f.is_finite());
Alex Crichtona914a612018-04-04 07:48:44 -0700545 Literal::_new(imp::Literal::f32_unsuffixed(f))
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700546 }
547
548 pub fn f32_suffixed(f: f32) -> Literal {
549 assert!(f.is_finite());
Alex Crichtona914a612018-04-04 07:48:44 -0700550 Literal::_new(imp::Literal::f32_suffixed(f))
Alex Crichton1a7f7622017-07-05 17:47:15 -0700551 }
552
553 pub fn string(string: &str) -> Literal {
Alex Crichtona914a612018-04-04 07:48:44 -0700554 Literal::_new(imp::Literal::string(string))
Alex Crichton1a7f7622017-07-05 17:47:15 -0700555 }
556
557 pub fn character(ch: char) -> Literal {
Alex Crichtona914a612018-04-04 07:48:44 -0700558 Literal::_new(imp::Literal::character(ch))
Alex Crichton76a5cc82017-05-23 07:01:44 -0700559 }
560
Alex Crichton9c2fb0a2017-05-26 08:49:31 -0700561 pub fn byte_string(s: &[u8]) -> Literal {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700562 Literal::_new(imp::Literal::byte_string(s))
Alex Crichton852d53d2017-05-19 19:25:08 -0700563 }
Alex Crichton76a5cc82017-05-23 07:01:44 -0700564
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700565 pub fn span(&self) -> Span {
Alex Crichtonb2c94622018-04-04 07:36:41 -0700566 Span::_new(self.inner.span())
Alex Crichton1a7f7622017-07-05 17:47:15 -0700567 }
568
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700569 pub fn set_span(&mut self, span: Span) {
Alex Crichtonb2c94622018-04-04 07:36:41 -0700570 self.inner.set_span(span.inner);
Alex Crichton31316622017-05-26 12:54:47 -0700571 }
Alex Crichton852d53d2017-05-19 19:25:08 -0700572}
573
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700574impl fmt::Debug for Literal {
575 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
576 self.inner.fmt(f)
Alex Crichton44bffbc2017-05-19 17:51:59 -0700577 }
578}
David Tolnaycb1b85f2017-06-03 16:40:35 -0700579
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700580impl fmt::Display for Literal {
581 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
582 self.inner.fmt(f)
583 }
584}
585
586pub mod token_stream {
587 use std::fmt;
588 use std::marker;
589 use std::rc::Rc;
590
David Tolnay48ea5042018-04-23 19:17:35 -0700591 use imp;
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700592 pub use TokenStream;
David Tolnayb28f38a2018-03-31 22:02:29 +0200593 use TokenTree;
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700594
595 pub struct IntoIter {
596 inner: imp::TokenTreeIter,
597 _marker: marker::PhantomData<Rc<()>>,
598 }
599
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700600 impl Iterator for IntoIter {
601 type Item = TokenTree;
602
603 fn next(&mut self) -> Option<TokenTree> {
604 self.inner.next()
605 }
606 }
607
608 impl fmt::Debug for IntoIter {
609 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
610 self.inner.fmt(f)
611 }
612 }
613
614 impl IntoIterator for TokenStream {
615 type Item = TokenTree;
616 type IntoIter = IntoIter;
617
618 fn into_iter(self) -> IntoIter {
619 IntoIter {
620 inner: self.inner.into_iter(),
621 _marker: marker::PhantomData,
622 }
623 }
624 }
625}