@@ -21,37 +21,41 @@ use std::env;
2121use std:: path:: Path ;
2222use std:: error:: Error ;
2323
24- use syntax:: diagnostics:: metadata:: { get_metadata_dir, ErrorMetadataMap } ;
24+ use syntax:: diagnostics:: metadata:: { get_metadata_dir, ErrorMetadataMap , ErrorMetadata } ;
2525
2626use rustdoc:: html:: markdown:: Markdown ;
2727use rustc_serialize:: json;
2828
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+ }
4034
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 ( ) ) ,
4341 }
4442 }
43+ }
4544
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 > > ;
4751}
4852
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 ;
5255
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>
5559<html>
5660<head>
5761<title>Rust Compiler Error Index</title>
@@ -66,12 +70,17 @@ r##"<!DOCTYPE html>
6670</style>
6771</head>
6872<body>
69- "##
70- ) ) ;
73+ "## ) ) ;
74+ Ok ( ( ) )
75+ }
7176
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+ }
7381
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 > > {
7584 // Enclose each error in a div so they can be shown/hidden en masse.
7685 let desc_desc = match info. description {
7786 Some ( _) => "error-described" ,
@@ -81,37 +90,114 @@ r##"<!DOCTYPE html>
8190 Some ( _) => "error-used" ,
8291 None => "error-unused" ,
8392 } ;
84- try!( write ! ( & mut output_file , "<div class=\" {} {}\" >" , desc_desc, use_desc) ) ;
93+ try!( write ! ( output , "<div class=\" {} {}\" >" , desc_desc, use_desc) ) ;
8594
8695 // Error title (with self-link).
87- try!( write ! ( & mut output_file ,
96+ try!( write ! ( output ,
8897 "<h2 id=\" {0}\" class=\" section-header\" ><a href=\" #{0}\" >{0}</a></h2>\n " ,
8998 err_code) ) ;
9099
91100 // Description rendered as markdown.
92101 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 " ) ) ,
95104 }
96105
97- try!( write ! ( & mut output_file, "</div>\n " ) ) ;
106+ try!( write ! ( output, "</div>\n " ) ) ;
107+ Ok ( ( ) )
98108 }
99109
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+ }
101115
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)
103174}
104175
105- fn main_with_result ( ) -> Result < ( ) , Box < Error > > {
176+ fn main_with_result ( format : OutputFormat ) -> Result < ( ) , Box < Error > > {
106177 let build_arch = try!( env:: var ( "CFG_BUILD" ) ) ;
107178 let metadata_dir = get_metadata_dir ( & build_arch) ;
108179 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+ }
110189 Ok ( ( ) )
111190}
112191
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+
113199fn main ( ) {
114- if let Err ( e) = main_with_result ( ) {
200+ if let Err ( e) = main_with_result ( parse_args ( ) ) {
115201 panic ! ( "{}" , e. description( ) ) ;
116202 }
117203}
0 commit comments