Skip to content

Commit

Permalink
add arguments to godbolt
Browse files Browse the repository at this point in the history
  • Loading branch information
tinaun committed Jun 18, 2021
1 parent 2d029fa commit f118536
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 12 deletions.
2 changes: 1 addition & 1 deletion src/crates.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ fn get_crate(args: &Args) -> Result<Option<Crate>, Error> {
.send()?
.json::<Crates>()?;

Ok(crate_list.crates.into_iter().nth(0))
Ok(crate_list.crates.into_iter().next())
}

pub fn search(args: Args) -> Result<(), Error> {
Expand Down
48 changes: 45 additions & 3 deletions src/godbolt.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::{api, commands::Args};
pub enum Compilation {
Success { asm: String },
Error { stderr: String },
Expand Down Expand Up @@ -32,17 +33,40 @@ struct GodboltResponse {
asm: GodboltOutput,
}

pub fn help(args: Args) -> Result<(), crate::Error> {
let message = "Compile Rust code using <https://rust.godbolt.org/>. Full optimizations are applied unless overriden.
```?godbolt flags={} rustc={} ``\u{200B}`code``\u{200B}` ```
Optional arguments:
\tflags: flags to pass to rustc invocation. Defaults to \"-Copt-level=3 --edition=2018\".
\trustc: compiler version to invoke. Defaults to `nightly`. Possible values: `nightly`, `beta` or full version like `1.45.2`.
";

api::send_reply(&args, &message)?;
Ok(())
}

/// Compile a given Rust source code file on Godbolt using the latest nightly compiler with
/// full optimizations (-O3)
/// full optimizations (-O3) by default
/// Returns a multiline string with the pretty printed assembly
pub fn compile_rust_source(
http: &reqwest::blocking::Client,
source_code: &str,
flags: &str,
rustc: &str,
) -> Result<Compilation, crate::Error> {
let cv = rustc_to_godbolt(rustc);
let cv = match cv {
Ok(c) => c,
Err(e) => {
return Ok(Compilation::Error { stderr: e });
}
};
info!("cv: rustc {}", cv);

let response: GodboltResponse = http
.execute(
http.post("https://godbolt.org/api/compiler/nightly/compile")
.query(&[("options", "-Copt-level=3")])
http.post(&format!("https://godbolt.org/api/compiler/{}/compile", cv))
.query(&[("options", &flags)])
.header(reqwest::header::ACCEPT, "application/json")
.body(source_code.to_owned())
.build()?,
Expand All @@ -61,3 +85,21 @@ pub fn compile_rust_source(
}
})
}

// converts a rustc version number to a godbolt compiler id
fn rustc_to_godbolt(rustc_version: &str) -> Result<String, String> {
match rustc_version {
"beta" => Ok("beta".to_string()),
"nightly" => Ok("nightly".to_string()),
// this heuristic is barebones but catches most obviously wrong things
// it doesn't know anything about valid rustc versions
ver if ver.contains('.') && !ver.contains(|c: char| c.is_alphabetic()) => {
let mut godbolt_version = "r".to_string();
for segment in ver.split('.') {
godbolt_version.push_str(segment);
}
Ok(godbolt_version)
}
other => Err(format!("invalid rustc version: `{}`", other)),
}
}
17 changes: 9 additions & 8 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,12 +149,18 @@ fn app() -> Result<(), Error> {
});
}

cmds.add("?godbolt ```\ncode```", |args| {
cmds.add("?godbolt flags={} version={} ```\ncode```", |args| {
let flags = args
.params
.get("flags")
.unwrap_or(&"-Copt-level=3 --edition=2018");
let rustc = args.params.get("rustc").unwrap_or(&"nightly");

let code = args
.params
.get("code")
.ok_or("Unable to retrieve param: code")?;
let (lang, text) = match godbolt::compile_rust_source(args.http, code)? {
let (lang, text) = match godbolt::compile_rust_source(args.http, code, flags, rustc)? {
godbolt::Compilation::Success { asm } => ("x86asm", asm),
godbolt::Compilation::Error { stderr } => ("rust", stderr),
};
Expand All @@ -169,12 +175,7 @@ fn app() -> Result<(), Error> {
Ok(())
});
cmds.help("?godbolt", "View assembly using Godbolt", |args| {
api::send_reply(
&args,
"Compile Rust code using https://rust.godbolt.org. Full optimizations are applied. \
```?godbolt ``\u{200B}`code``\u{200B}` ```",
)?;
Ok(())
godbolt::help(args)
});

// Slow mode.
Expand Down

0 comments on commit f118536

Please sign in to comment.