1
+ import std:: getopts;
2
+
3
+ export output_format :: { } ;
4
+ export output_style :: { } ;
5
+ export config;
6
+ export parse_config;
7
+
8
+ #[ doc = "The type of document to output" ]
9
+ enum output_format {
10
+ #[ doc = "Markdown" ]
11
+ markdown,
12
+ #[ doc = "HTML, via markdown and pandoc" ]
13
+ pandoc_html
14
+ }
15
+
16
+ #[ doc = "How to organize the output" ]
17
+ enum output_style {
18
+ #[ doc = "All in a single document" ]
19
+ doc_per_crate,
20
+ #[ doc = "Each module in its own document" ]
21
+ doc_per_mod
22
+ }
23
+
24
+ #[ doc = "The configuration for a rustdoc session" ]
25
+ type config = {
26
+ input_crate : str ,
27
+ output_dir : str ,
28
+ output_format : output_format ,
29
+ output_style : output_style ,
30
+ pandoc_cmd : option < str >
31
+ } ;
32
+
33
+ fn opt_output_dir ( ) -> str { "output-dir" }
34
+ fn opt_output_format ( ) -> str { "output-format" }
35
+ fn opt_output_style ( ) -> str { "output-style" }
36
+ fn opt_pandoc_cmd ( ) -> str { "pandoc-cmd" }
37
+
38
+ fn opts ( ) -> [ ( getopts:: opt , str ) ] {
39
+ [
40
+ ( getopts:: optopt ( opt_output_dir ( ) ) ,
41
+ "put documents here" ) ,
42
+ ( getopts:: optopt ( opt_output_format ( ) ) ,
43
+ "either 'markdown' or 'html'" ) ,
44
+ ( getopts:: optopt ( opt_output_style ( ) ) ,
45
+ "either 'doc-per-crate' or 'doc-per-mod'" ) ,
46
+ ( getopts:: optopt ( opt_pandoc_cmd ( ) ) ,
47
+ "the command for running pandoc" )
48
+ ]
49
+ }
50
+
51
+ fn default_config ( input_crate : str ) -> config {
52
+ {
53
+ input_crate: input_crate,
54
+ output_dir: "." ,
55
+ output_format: pandoc_html,
56
+ output_style: doc_per_mod,
57
+ pandoc_cmd: none
58
+ }
59
+ }
60
+
61
+ fn parse_config( args : [ str ] ) -> result:: t < config , str > {
62
+ let args = vec:: tail ( args) ;
63
+ let opts = tuple:: first ( vec:: unzip ( opts ( ) ) ) ;
64
+ alt getopts:: getopts ( args, opts) {
65
+ result:: ok( match ) {
66
+ if vec:: len( match . free) == 1 u {
67
+ let input_crate = vec:: head( match . free) ;
68
+ config_from_opts( input_crate, match )
69
+ } else if vec:: is_empty ( match . free) {
70
+ result:: err ( "no crates specified" )
71
+ } else {
72
+ result:: err ( "multiple crates specified" )
73
+ }
74
+ }
75
+ result:: err ( f) {
76
+ result:: err( getopts:: fail_str( f) )
77
+ }
78
+ }
79
+ }
80
+
81
+ fn config_from_opts(
82
+ input_crate: str ,
83
+ match: getopts:: match
84
+ ) -> result:: t < config , str > {
85
+
86
+ let config = default_config( input_crate) ;
87
+ let result = result:: ok( config) ;
88
+ let result = result:: chain( result) { |config|
89
+ let output_dir = getopts:: opt_maybe_str( match, opt_output_dir( ) ) ;
90
+ result:: ok( {
91
+ output_dir: option:: from_maybe( config. output_dir, output_dir)
92
+ with config
93
+ } )
94
+ } ;
95
+ let result = result:: chain( result) { |config|
96
+ let output_format = getopts:: opt_maybe_str(
97
+ match, opt_output_format( ) ) ;
98
+ option:: maybe( result:: ok( config) , output_format) { |output_format|
99
+ result:: chain( parse_output_format( output_format) ) { |output_format|
100
+ result:: ok( {
101
+ output_format: output_format
102
+ with config
103
+ } )
104
+ }
105
+ }
106
+ } ;
107
+ let result = result:: chain( result) { |config|
108
+ let output_style = getopts:: opt_maybe_str( match, opt_output_style( ) ) ;
109
+ option:: maybe( result:: ok( config) , output_style) { |output_style|
110
+ result:: chain( parse_output_style( output_style) ) { |output_style|
111
+ result:: ok( {
112
+ output_style: output_style
113
+ with config
114
+ } )
115
+ }
116
+ }
117
+ } ;
118
+ let result = result:: chain( result) { |config|
119
+ let pandoc_cmd = getopts:: opt_maybe_str( match, opt_pandoc_cmd( ) ) ;
120
+ let pandoc_cmd = maybe_find_pandoc( config, pandoc_cmd) ;
121
+ result:: chain( pandoc_cmd) { |pandoc_cmd|
122
+ result:: ok( {
123
+ pandoc_cmd: pandoc_cmd
124
+ with config
125
+ } )
126
+ }
127
+ } ;
128
+ ret result;
129
+ }
130
+
131
+ fn parse_output_format( output_format: str ) -> result:: t < output_format , str > {
132
+ alt output_format {
133
+ "markdown" { result:: ok( markdown) }
134
+ "html" { result:: ok( pandoc_html) }
135
+ _ { result:: err( #fmt( "unknown output format '%s'" , output_format) ) }
136
+ }
137
+ }
138
+
139
+ fn parse_output_style( output_style: str ) -> result:: t < output_style , str > {
140
+ alt output_style {
141
+ "doc-per-crate" { result:: ok( doc_per_crate) }
142
+ "doc-per-mod" { result:: ok( doc_per_mod) }
143
+ _ { result:: err( #fmt( "unknown output style '%s'" , output_style) ) }
144
+ }
145
+ }
146
+
147
+ fn maybe_find_pandoc(
148
+ _config: config,
149
+ maybe_pandoc_cmd: option < str >
150
+ ) -> result:: t < option < str > , str > {
151
+ // FIXME: When we actually need pandoc then look for it first
152
+ // on the path, then in cabal; test to make sure pandoc works
153
+ alt maybe_pandoc_cmd {
154
+ some( pandoc_cmd) { result:: ok( some( pandoc_cmd) ) }
155
+ none { result : : ok( some( "pandoc" ) ) }
156
+ }
157
+ }
158
+
159
+ #[ test]
160
+ fn should_error_with_no_crates( ) {
161
+ let config = parse_config( [ "rustdoc" ] ) ;
162
+ assert result:: get_err( config) == "no crates specified" ;
163
+ }
164
+
165
+ #[ test]
166
+ fn should_error_with_multiple_crates( ) {
167
+ let config = parse_config( [ "rustdoc" , "crate1.rc" , "crate2.rc" ] ) ;
168
+ assert result:: get_err( config) == "multiple crates specified" ;
169
+ }
170
+
171
+ #[ test]
172
+ fn should_set_output_dir_to_cwd_if_not_provided( ) {
173
+ let config = parse_config( [ "rustdoc" , "crate.rc" ] ) ;
174
+ assert result:: get( config) . output_dir == "." ;
175
+ }
176
+
177
+ #[ test]
178
+ fn should_set_output_dir_if_provided( ) {
179
+ let config = parse_config( [
180
+ "rustdoc" , "crate.rc" , "--output-dir" , "snuggles"
181
+ ] ) ;
182
+ assert result:: get( config) . output_dir == "snuggles" ;
183
+ }
184
+
185
+ #[ test]
186
+ fn should_set_output_format_to_pandoc_html_if_not_provided( ) {
187
+ let config = parse_config( [ "rustdoc" , "crate.rc" ] ) ;
188
+ assert result:: get( config) . output_format == pandoc_html;
189
+ }
190
+
191
+ #[ test]
192
+ fn should_set_output_format_to_markdown_if_requested( ) {
193
+ let config = parse_config( [
194
+ "rustdoc" , "crate.rc" , "--output-format" , "markdown"
195
+ ] ) ;
196
+ assert result:: get( config) . output_format == markdown;
197
+ }
198
+
199
+ #[ test]
200
+ fn should_set_output_format_to_pandoc_html_if_requested( ) {
201
+ let config = parse_config( [
202
+ "rustdoc" , "crate.rc" , "--output-format" , "html"
203
+ ] ) ;
204
+ assert result:: get( config) . output_format == pandoc_html;
205
+ }
206
+
207
+ #[ test]
208
+ fn should_error_on_bogus_format( ) {
209
+ let config = parse_config( [
210
+ "rustdoc" , "crate.rc" , "--output-format" , "bogus"
211
+ ] ) ;
212
+ assert result:: get_err( config) == "unknown output format 'bogus'" ;
213
+ }
214
+
215
+ #[ test]
216
+ fn should_set_output_style_to_doc_per_mod_by_default( ) {
217
+ let config = parse_config( [ "rustdoc" , "crate.rc" ] ) ;
218
+ assert result:: get( config) . output_style == doc_per_mod;
219
+ }
220
+
221
+ #[ test]
222
+ fn should_set_output_style_to_one_doc_if_requested( ) {
223
+ let config = parse_config( [
224
+ "rustdoc" , "crate.rc" , "--output-style" , "doc-per-crate"
225
+ ] ) ;
226
+ assert result:: get( config) . output_style == doc_per_crate;
227
+ }
228
+
229
+ #[ test]
230
+ fn should_set_output_style_to_doc_per_mod_if_requested( ) {
231
+ let config = parse_config( [
232
+ "rustdoc" , "crate.rc" , "--output-style" , "doc-per-mod"
233
+ ] ) ;
234
+ assert result:: get( config) . output_style == doc_per_mod;
235
+ }
236
+
237
+ #[ test]
238
+ fn should_error_on_bogus_output_style( ) {
239
+ let config = parse_config( [
240
+ "rustdoc" , "crate.rc" , "--output-style" , "bogus"
241
+ ] ) ;
242
+ assert result:: get_err( config) == "unknown output style 'bogus'" ;
243
+ }
244
+
245
+ #[ test]
246
+ fn should_set_pandoc_command_if_requested( ) {
247
+ let config = parse_config( [
248
+ "rustdoc" , "crate.rc" , "--pandoc-cmd" , "panda-bear-doc"
249
+ ] ) ;
250
+ assert result:: get( config) . pandoc_cmd == some( "panda-bear-doc" ) ;
251
+ }
252
+
253
+ #[ test]
254
+ fn should_set_pandoc_command_when_using_pandoc( ) {
255
+ let config = parse_config( [ "rustdoc" , "crate.rc" ] ) ;
256
+ assert result:: get( config) . pandoc_cmd == some( "pandoc" ) ;
257
+ }
0 commit comments