combine_proc_macro/
diagnostic.rs1use crate::input::Token;
4use combine::ParseError;
5use combine::stream::StreamOnce;
6use proc_macro2::{TokenTree, TokenStream};
7use std::convert::TryFrom;
8use std::fmt;
9
10const DEFAULT_MAX_TRAILING: usize = 50;
11
12#[derive(Debug)]
26pub struct Incomplete {
27 trailing: Vec<TokenTree>,
28
29 max_trailing: usize,
31}
32
33impl Incomplete {
34 pub fn from_stream<I>(mut input: I) -> Option<Incomplete>
35 where
36 I: StreamOnce<Item = Token>,
37 I::Error: ParseError<I::Item, I::Range, I::Position>,
38 {
39 let mut trailing = Vec::new();
40 while let Ok(tok) = input.uncons() {
41 trailing.extend(TokenTree::try_from(tok).into_iter());
42 if trailing.len() > DEFAULT_MAX_TRAILING {
43 break;
44 }
45 }
46 if trailing.len() > 0 {
47 Some(Incomplete {
48 trailing,
49 max_trailing: DEFAULT_MAX_TRAILING,
50 })
51 } else {
52 None
53 }
54 }
55}
56
57impl fmt::Display for Incomplete {
58 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
59 let total = self.trailing.len();
60 let mut stream = TokenStream::new();
61 stream.extend(self.trailing.iter().take(self.max_trailing).cloned());
62 if total > self.max_trailing {
63 write!(f, "{} [and {} more ...]", stream, total - self.max_trailing)
64 } else {
65 write!(f, "{}", stream)
66 }
67 }
68}