@@ -13,6 +13,7 @@ mod command_history;
1313mod commands;
1414mod crates;
1515mod db;
16+ mod godbolt;
1617mod jobs;
1718mod playground;
1819mod schema;
@@ -148,6 +149,34 @@ fn app() -> Result<(), Error> {
148149 } ) ;
149150 }
150151
152+ cmds. add ( "?godbolt ```\n code```" , |args| {
153+ let code = args
154+ . params
155+ . get ( "code" )
156+ . ok_or ( "Unable to retrieve param: code" ) ?;
157+ let ( lang, text) = match godbolt:: compile_rust_source ( args. http , code) ? {
158+ godbolt:: Compilation :: Success { asm } => ( "x86asm" , asm) ,
159+ godbolt:: Compilation :: Error { stderr } => ( "rust" , stderr) ,
160+ } ;
161+
162+ reply_potentially_long_text (
163+ & args,
164+ & format ! ( "```{}\n {}" , lang, text) ,
165+ "\n ```" ,
166+ "Note: the output was truncated" ,
167+ ) ?;
168+
169+ Ok ( ( ) )
170+ } ) ;
171+ cmds. help ( "?godbolt" , "View assembly using Godbolt" , |args| {
172+ api:: send_reply (
173+ & args,
174+ "Compile Rust code using https://rust.godbolt.org. Full optimizations are applied. \
175+ ```?godbolt ``\u{200B} `code``\u{200B} ` ```",
176+ ) ?;
177+ Ok ( ( ) )
178+ } ) ;
179+
151180 // Slow mode.
152181 // 0 seconds disables slowmode
153182 cmds. add_protected ( "?slowmode {channel} {seconds}" , api:: slow_mode, api:: is_mod) ;
@@ -202,6 +231,40 @@ fn app() -> Result<(), Error> {
202231 Ok ( ( ) )
203232}
204233
234+ /// Send a Discord reply message and truncate the message with a given truncation message if the
235+ /// text is too long.
236+ ///
237+ /// Only `text_body` is truncated. `text_end` will always be appended at the end. This is useful
238+ /// for example for large code blocks. You will want to truncate the code block contents, but the
239+ /// finalizing \`\`\` should always stay - that's what `text_end` is for.
240+ fn reply_potentially_long_text (
241+ args : & Args ,
242+ text_body : & str ,
243+ text_end : & str ,
244+ truncation_msg : & str ,
245+ ) -> Result < ( ) , Error > {
246+ let msg = if text_body. len ( ) + text_end. len ( ) > 2000 {
247+ // This is how long the text body may be at max to conform to Discord's limit
248+ let available_space = 2000 - text_end. len ( ) - truncation_msg. len ( ) ;
249+
250+ let mut cut_off_point = available_space;
251+ while !text_body. is_char_boundary ( cut_off_point) {
252+ cut_off_point -= 1 ;
253+ }
254+
255+ format ! (
256+ "{}{}{}" ,
257+ & text_body[ ..cut_off_point] ,
258+ text_end,
259+ truncation_msg
260+ )
261+ } else {
262+ format ! ( "{}{}" , text_body, text_end)
263+ } ;
264+
265+ api:: send_reply ( args, & msg)
266+ }
267+
205268fn main_menu ( args : & Args , commands : & IndexMap < & str , ( & str , GuardFn ) > ) -> String {
206269 let mut menu = format ! ( "Commands:\n " ) ;
207270
0 commit comments