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
use crate::input::Token;
use combine::ParseError;
use combine::stream::StreamOnce;
use proc_macro2::{TokenTree, TokenStream};
use std::convert::TryFrom;
use std::fmt;
const DEFAULT_MAX_TRAILING: usize = 50;
#[derive(Debug)]
pub struct Incomplete {
trailing: Vec<TokenTree>,
max_trailing: usize,
}
impl Incomplete {
pub fn from_stream<I>(mut input: I) -> Option<Incomplete>
where
I: StreamOnce<Item = Token>,
I::Error: ParseError<I::Item, I::Range, I::Position>,
{
let mut trailing = Vec::new();
while let Ok(tok) = input.uncons() {
trailing.extend(TokenTree::try_from(tok).into_iter());
if trailing.len() > DEFAULT_MAX_TRAILING {
break;
}
}
if trailing.len() > 0 {
Some(Incomplete {
trailing,
max_trailing: DEFAULT_MAX_TRAILING,
})
} else {
None
}
}
}
impl fmt::Display for Incomplete {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let total = self.trailing.len();
let mut stream = TokenStream::new();
stream.extend(self.trailing.iter().take(self.max_trailing).cloned());
if total > self.max_trailing {
write!(f, "{} [and {} more ...]", stream, total - self.max_trailing)
} else {
write!(f, "{}", stream)
}
}
}