@@ -21,37 +21,41 @@ use std::env;
21
21
use std:: path:: Path ;
22
22
use std:: error:: Error ;
23
23
24
- use syntax:: diagnostics:: metadata:: { get_metadata_dir, ErrorMetadataMap } ;
24
+ use syntax:: diagnostics:: metadata:: { get_metadata_dir, ErrorMetadataMap , ErrorMetadata } ;
25
25
26
26
use rustdoc:: html:: markdown:: Markdown ;
27
27
use rustc_serialize:: json;
28
28
29
- /// Load all the metadata files from `metadata_dir` into an in-memory map.
30
- fn load_all_errors ( metadata_dir : & Path ) -> Result < ErrorMetadataMap , Box < Error > > {
31
- let mut all_errors = BTreeMap :: new ( ) ;
32
-
33
- for entry in try!( read_dir ( metadata_dir) ) {
34
- let path = try!( entry) . path ( ) ;
35
-
36
- let mut metadata_str = String :: new ( ) ;
37
- try!( File :: open ( & path) . and_then ( |mut f| f. read_to_string ( & mut metadata_str) ) ) ;
38
-
39
- let some_errors: ErrorMetadataMap = try!( json:: decode ( & metadata_str) ) ;
29
+ enum OutputFormat {
30
+ HTML ( HTMLFormatter ) ,
31
+ Markdown ( MarkdownFormatter ) ,
32
+ Unknown ( String ) ,
33
+ }
40
34
41
- for ( err_code, info) in some_errors {
42
- all_errors. insert ( err_code, info) ;
35
+ impl OutputFormat {
36
+ fn from ( format : & str ) -> OutputFormat {
37
+ match & * format. to_lowercase ( ) {
38
+ "html" => OutputFormat :: HTML ( HTMLFormatter ) ,
39
+ "markdown" => OutputFormat :: Markdown ( MarkdownFormatter ) ,
40
+ s => OutputFormat :: Unknown ( s. to_owned ( ) ) ,
43
41
}
44
42
}
43
+ }
45
44
46
- Ok ( all_errors)
45
+ trait Formatter {
46
+ fn header ( & self , output : & mut Write ) -> Result < ( ) , Box < Error > > ;
47
+ fn title ( & self , output : & mut Write ) -> Result < ( ) , Box < Error > > ;
48
+ fn error_code_block ( & self , output : & mut Write , info : & ErrorMetadata ,
49
+ err_code : & str ) -> Result < ( ) , Box < Error > > ;
50
+ fn footer ( & self , output : & mut Write ) -> Result < ( ) , Box < Error > > ;
47
51
}
48
52
49
- /// Output an HTML page for the errors in `err_map` to `output_path`.
50
- fn render_error_page ( err_map : & ErrorMetadataMap , output_path : & Path ) -> Result < ( ) , Box < Error > > {
51
- let mut output_file = try!( File :: create ( output_path) ) ;
53
+ struct HTMLFormatter ;
54
+ struct MarkdownFormatter ;
52
55
53
- try!( write ! ( & mut output_file,
54
- r##"<!DOCTYPE html>
56
+ impl Formatter for HTMLFormatter {
57
+ fn header ( & self , output : & mut Write ) -> Result < ( ) , Box < Error > > {
58
+ try!( write ! ( output, r##"<!DOCTYPE html>
55
59
<html>
56
60
<head>
57
61
<title>Rust Compiler Error Index</title>
@@ -66,12 +70,17 @@ r##"<!DOCTYPE html>
66
70
</style>
67
71
</head>
68
72
<body>
69
- "##
70
- ) ) ;
73
+ "## ) ) ;
74
+ Ok ( ( ) )
75
+ }
71
76
72
- try!( write ! ( & mut output_file, "<h1>Rust Compiler Error Index</h1>\n " ) ) ;
77
+ fn title ( & self , output : & mut Write ) -> Result < ( ) , Box < Error > > {
78
+ try!( write ! ( output, "<h1>Rust Compiler Error Index</h1>\n " ) ) ;
79
+ Ok ( ( ) )
80
+ }
73
81
74
- for ( err_code, info) in err_map {
82
+ fn error_code_block ( & self , output : & mut Write , info : & ErrorMetadata ,
83
+ err_code : & str ) -> Result < ( ) , Box < Error > > {
75
84
// Enclose each error in a div so they can be shown/hidden en masse.
76
85
let desc_desc = match info. description {
77
86
Some ( _) => "error-described" ,
@@ -81,37 +90,114 @@ r##"<!DOCTYPE html>
81
90
Some ( _) => "error-used" ,
82
91
None => "error-unused" ,
83
92
} ;
84
- try!( write ! ( & mut output_file , "<div class=\" {} {}\" >" , desc_desc, use_desc) ) ;
93
+ try!( write ! ( output , "<div class=\" {} {}\" >" , desc_desc, use_desc) ) ;
85
94
86
95
// Error title (with self-link).
87
- try!( write ! ( & mut output_file ,
96
+ try!( write ! ( output ,
88
97
"<h2 id=\" {0}\" class=\" section-header\" ><a href=\" #{0}\" >{0}</a></h2>\n " ,
89
98
err_code) ) ;
90
99
91
100
// Description rendered as markdown.
92
101
match info. description {
93
- Some ( ref desc) => try!( write ! ( & mut output_file , "{}" , Markdown ( desc) ) ) ,
94
- None => try!( write ! ( & mut output_file , "<p>No description.</p>\n " ) ) ,
102
+ Some ( ref desc) => try!( write ! ( output , "{}" , Markdown ( desc) ) ) ,
103
+ None => try!( write ! ( output , "<p>No description.</p>\n " ) ) ,
95
104
}
96
105
97
- try!( write ! ( & mut output_file, "</div>\n " ) ) ;
106
+ try!( write ! ( output, "</div>\n " ) ) ;
107
+ Ok ( ( ) )
98
108
}
99
109
100
- try!( write ! ( & mut output_file, "</body>\n </html>" ) ) ;
110
+ fn footer ( & self , output : & mut Write ) -> Result < ( ) , Box < Error > > {
111
+ try!( write ! ( output, "</body>\n </html>" ) ) ;
112
+ Ok ( ( ) )
113
+ }
114
+ }
101
115
102
- Ok ( ( ) )
116
+ impl Formatter for MarkdownFormatter {
117
+ #[ allow( unused_variables) ]
118
+ fn header ( & self , output : & mut Write ) -> Result < ( ) , Box < Error > > {
119
+ Ok ( ( ) )
120
+ }
121
+
122
+ fn title ( & self , output : & mut Write ) -> Result < ( ) , Box < Error > > {
123
+ try!( write ! ( output, "# Rust Compiler Error Index\n " ) ) ;
124
+ Ok ( ( ) )
125
+ }
126
+
127
+ fn error_code_block ( & self , output : & mut Write , info : & ErrorMetadata ,
128
+ err_code : & str ) -> Result < ( ) , Box < Error > > {
129
+ Ok ( match info. description {
130
+ Some ( ref desc) => try!( write ! ( output, "## {}\n {}\n " , err_code, desc) ) ,
131
+ None => ( ) ,
132
+ } )
133
+ }
134
+
135
+ #[ allow( unused_variables) ]
136
+ fn footer ( & self , output : & mut Write ) -> Result < ( ) , Box < Error > > {
137
+ Ok ( ( ) )
138
+ }
139
+ }
140
+
141
+ /// Load all the metadata files from `metadata_dir` into an in-memory map.
142
+ fn load_all_errors ( metadata_dir : & Path ) -> Result < ErrorMetadataMap , Box < Error > > {
143
+ let mut all_errors = BTreeMap :: new ( ) ;
144
+
145
+ for entry in try!( read_dir ( metadata_dir) ) {
146
+ let path = try!( entry) . path ( ) ;
147
+
148
+ let mut metadata_str = String :: new ( ) ;
149
+ try!( File :: open ( & path) . and_then ( |mut f| f. read_to_string ( & mut metadata_str) ) ) ;
150
+
151
+ let some_errors: ErrorMetadataMap = try!( json:: decode ( & metadata_str) ) ;
152
+
153
+ for ( err_code, info) in some_errors {
154
+ all_errors. insert ( err_code, info) ;
155
+ }
156
+ }
157
+
158
+ Ok ( all_errors)
159
+ }
160
+
161
+ /// Output an HTML page for the errors in `err_map` to `output_path`.
162
+ fn render_error_page < T : Formatter > ( err_map : & ErrorMetadataMap , output_path : & Path ,
163
+ formatter : T ) -> Result < ( ) , Box < Error > > {
164
+ let mut output_file = try!( File :: create ( output_path) ) ;
165
+
166
+ try!( formatter. header ( & mut output_file) ) ;
167
+ try!( formatter. title ( & mut output_file) ) ;
168
+
169
+ for ( err_code, info) in err_map {
170
+ try!( formatter. error_code_block ( & mut output_file, info, err_code) ) ;
171
+ }
172
+
173
+ formatter. footer ( & mut output_file)
103
174
}
104
175
105
- fn main_with_result ( ) -> Result < ( ) , Box < Error > > {
176
+ fn main_with_result ( format : OutputFormat ) -> Result < ( ) , Box < Error > > {
106
177
let build_arch = try!( env:: var ( "CFG_BUILD" ) ) ;
107
178
let metadata_dir = get_metadata_dir ( & build_arch) ;
108
179
let err_map = try!( load_all_errors ( & metadata_dir) ) ;
109
- try!( render_error_page ( & err_map, Path :: new ( "doc/error-index.html" ) ) ) ;
180
+ match format {
181
+ OutputFormat :: Unknown ( s) => panic ! ( "Unknown output format: {}" , s) ,
182
+ OutputFormat :: HTML ( h) => try!( render_error_page ( & err_map,
183
+ Path :: new ( "doc/error-index.html" ) ,
184
+ h) ) ,
185
+ OutputFormat :: Markdown ( m) => try!( render_error_page ( & err_map,
186
+ Path :: new ( "doc/error-index.md" ) ,
187
+ m) ) ,
188
+ }
110
189
Ok ( ( ) )
111
190
}
112
191
192
+ fn parse_args ( ) -> OutputFormat {
193
+ for arg in env:: args ( ) . skip ( 1 ) {
194
+ return OutputFormat :: from ( & arg) ;
195
+ }
196
+ OutputFormat :: from ( "html" )
197
+ }
198
+
113
199
fn main ( ) {
114
- if let Err ( e) = main_with_result ( ) {
200
+ if let Err ( e) = main_with_result ( parse_args ( ) ) {
115
201
panic ! ( "{}" , e. description( ) ) ;
116
202
}
117
203
}
0 commit comments