@@ -13,6 +13,7 @@ mod command_history;
13
13
mod commands;
14
14
mod crates;
15
15
mod db;
16
+ mod godbolt;
16
17
mod jobs;
17
18
mod playground;
18
19
mod schema;
@@ -148,6 +149,34 @@ fn app() -> Result<(), Error> {
148
149
} ) ;
149
150
}
150
151
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
+
151
180
// Slow mode.
152
181
// 0 seconds disables slowmode
153
182
cmds. add_protected ( "?slowmode {channel} {seconds}" , api:: slow_mode, api:: is_mod) ;
@@ -202,6 +231,40 @@ fn app() -> Result<(), Error> {
202
231
Ok ( ( ) )
203
232
}
204
233
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
+
205
268
fn main_menu ( args : & Args , commands : & IndexMap < & str , ( & str , GuardFn ) > ) -> String {
206
269
let mut menu = format ! ( "Commands:\n " ) ;
207
270
0 commit comments