1+ use crate :: { api, commands:: Args } ;
12pub enum Compilation {
23 Success { asm : String } ,
34 Error { stderr : String } ,
@@ -32,17 +33,40 @@ struct GodboltResponse {
3233 asm : GodboltOutput ,
3334}
3435
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+
3548/// 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
3750/// Returns a multiline string with the pretty printed assembly
3851pub fn compile_rust_source (
3952 http : & reqwest:: blocking:: Client ,
4053 source_code : & str ,
54+ flags : & str ,
55+ rustc : & str ,
4156) -> 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+
4266 let response: GodboltResponse = http
4367 . 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 ) ] )
4670 . header ( reqwest:: header:: ACCEPT , "application/json" )
4771 . body ( source_code. to_owned ( ) )
4872 . build ( ) ?,
@@ -61,3 +85,21 @@ pub fn compile_rust_source(
6185 }
6286 } )
6387}
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