1
+ use crate :: { api, commands:: Args } ;
1
2
pub enum Compilation {
2
3
Success { asm : String } ,
3
4
Error { stderr : String } ,
@@ -32,17 +33,40 @@ struct GodboltResponse {
32
33
asm : GodboltOutput ,
33
34
}
34
35
36
+ pub fn help ( args : Args ) -> Result < ( ) , crate :: Error > {
37
+ let message = "Compile Rust code using <https://rust.godbolt.org/>. Full optimizations are applied unless overriden.
38
+ ```?godbolt flags={} rustc={} ``\u{200B} `code``\u{200B} ` ```
39
+ Optional arguments:
40
+ \t flags: flags to pass to rustc invocation. Defaults to \" -Copt-level=3 --edition=2018\" .
41
+ \t rustc: compiler version to invoke. Defaults to `nightly`. Possible values: `nightly`, `beta` or full version like `1.45.2`.
42
+ " ;
43
+
44
+ api:: send_reply ( & args, & message) ?;
45
+ Ok ( ( ) )
46
+ }
47
+
35
48
/// Compile a given Rust source code file on Godbolt using the latest nightly compiler with
36
- /// full optimizations (-O3)
49
+ /// full optimizations (-O3) by default
37
50
/// Returns a multiline string with the pretty printed assembly
38
51
pub fn compile_rust_source (
39
52
http : & reqwest:: blocking:: Client ,
40
53
source_code : & str ,
54
+ flags : & str ,
55
+ rustc : & str ,
41
56
) -> Result < Compilation , crate :: Error > {
57
+ let cv = rustc_to_godbolt ( rustc) ;
58
+ let cv = match cv {
59
+ Ok ( c) => c,
60
+ Err ( e) => {
61
+ return Ok ( Compilation :: Error { stderr : e } ) ;
62
+ }
63
+ } ;
64
+ info ! ( "cv: rustc {}" , cv) ;
65
+
42
66
let response: GodboltResponse = http
43
67
. execute (
44
- http. post ( "https://godbolt.org/api/compiler/nightly /compile" )
45
- . query ( & [ ( "options" , "-Copt-level=3" ) ] )
68
+ http. post ( & format ! ( "https://godbolt.org/api/compiler/{} /compile" , cv ) )
69
+ . query ( & [ ( "options" , & flags ) ] )
46
70
. header ( reqwest:: header:: ACCEPT , "application/json" )
47
71
. body ( source_code. to_owned ( ) )
48
72
. build ( ) ?,
@@ -61,3 +85,21 @@ pub fn compile_rust_source(
61
85
}
62
86
} )
63
87
}
88
+
89
+ // converts a rustc version number to a godbolt compiler id
90
+ fn rustc_to_godbolt ( rustc_version : & str ) -> Result < String , String > {
91
+ match rustc_version {
92
+ "beta" => Ok ( "beta" . to_string ( ) ) ,
93
+ "nightly" => Ok ( "nightly" . to_string ( ) ) ,
94
+ // this heuristic is barebones but catches most obviously wrong things
95
+ // it doesn't know anything about valid rustc versions
96
+ ver if ver. contains ( '.' ) && !ver. contains ( |c : char | c. is_alphabetic ( ) ) => {
97
+ let mut godbolt_version = "r" . to_string ( ) ;
98
+ for segment in ver. split ( '.' ) {
99
+ godbolt_version. push_str ( segment) ;
100
+ }
101
+ Ok ( godbolt_version)
102
+ }
103
+ other => Err ( format ! ( "invalid rustc version: `{}`" , other) ) ,
104
+ }
105
+ }
0 commit comments