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
use std::fmt;
use ::syntex_syntax::print::pprust::ty_to_string;
use ::syntex_syntax::{codemap, symbol, ast};
use ::dot::escape_html;
#[derive(Debug, Eq, PartialEq, Clone)]
pub struct Enum<'a> {
pub vis: &'a ast::Visibility,
pub name: symbol::InternedString,
pub params: Vec<symbol::InternedString>,
pub variants: Vec<(symbol::InternedString, Vec<String>)>,
}
impl <'a>From<(&'a ast::Item, &'a Vec<ast::TyParam>, &'a Vec<ast::Variant>)> for Enum<'a> {
fn from((item, ty_params, variants): (&'a ast::Item, &'a Vec<ast::TyParam>, &'a Vec<ast::Variant>)) -> Enum<'a> {
Enum {
vis: &item.vis,
name: item.ident.name.as_str(),
params: ty_params.iter()
.map(|&ast::TyParam {attrs: _, ident: ast::Ident {name, ..}, ..}| name.as_str())
.collect::<Vec<symbol::InternedString>>(),
variants: variants.iter()
.map(|&codemap::Spanned {node: ast::Variant_ {name: ast::Ident {name, ..}, attrs: _, ref data, ..}, ..}| {
if let &ast::VariantData::Tuple(ref struct_field, _) = data {
(name.as_str(),
struct_field.iter()
.filter_map(|&ast::StructField { span: _, ident: _, vis: _, id: _, ref ty, .. }| Some(ty_to_string(&ty)))
.collect::<Vec<String>>())
} else {
(name.as_str(), Vec::new())
}
})
.collect::<Vec<(symbol::InternedString, Vec<String>)>>(),
}
}
}
impl <'a>fmt::Display for Enum<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if self.variants.is_empty() {
write!(f, "<<<Enumeration>>>\n{name}", name = self.name)
} else {
write!(f, "<<<Enumeration>>>\n{name}|{variants}",
name = self.name,
variants = escape_html(self.variants.iter()
.map(|&(ref name, ref struct_field): &(symbol::InternedString, Vec<String>)|
if struct_field.is_empty() {
format!("{}", name)
} else {
format!("{}({})", name, struct_field.join(", "))
}
)
.collect::<Vec<String>>()
.join("\n")
.as_str()),
)
}
}
}