diff --git a/src/commands/playground/util.rs b/src/commands/playground/util.rs index 9d2196b..3409ca6 100644 --- a/src/commands/playground/util.rs +++ b/src/commands/playground/util.rs @@ -210,6 +210,7 @@ pub fn maybe_wrapped( use quote::quote; use syn::{parse::Parse, *}; + // We use syn to check whether there is a main function. struct Inline { attrs: Vec, stmts: Vec, @@ -230,36 +231,42 @@ pub fn maybe_wrapped( } } - let Ok(Inline { attrs, mut stmts }) = parse_str::(code) else { + let Ok(Inline { .. }) = parse_str::(code) else { return Cow::Borrowed(code); }; + + // These string subsitutions are not quite optimal, but they perfectly preserve formatting, which is very important. + // This function must not change the formatting of the supplied code or it will be confusing and hard to use. + + // fn main boilerplate + let mut after_crate_attrs = match result_handling { + ResultHandling::None => "fn main() {\n", + ResultHandling::Discard => "fn main() { let _ = {\n", + ResultHandling::Print => "fn main() { println!(\"{:?}\", {\n", + } + .to_owned(); + if unsf { - stmts = vec![Stmt::Expr( - Expr::Unsafe(ExprUnsafe { - attrs: vec![], - unsafe_token: syn::token::Unsafe::default(), - block: Block { - brace_token: syn::token::Brace::default(), - stmts, - }, - }), - None, - )]; + after_crate_attrs = format!("{after_crate_attrs}unsafe {{"); } - match result_handling { - ResultHandling::None => quote! { #(#attrs)* fn main() { #(#stmts)* } }, - ResultHandling::Discard => { - quote! { #(#attrs)* fn main() { _ = (|| { #(#stmts)* })() } } - } - ResultHandling::Print if pretty => { - quote! { #(#attrs)* fn main() { ::std::println!("{:#?}", (|| { #(#stmts)* })()) } } - } - ResultHandling::Print => { - quote! { #(#attrs)* fn main() { ::std::println!("{:?}", (|| { #(#stmts)* })()) } } - } + + // fn main boilerplate counterpart + let mut after_code = match result_handling { + ResultHandling::None => "}", + ResultHandling::Discard => "}; }", + ResultHandling::Print => "}); }", + } + .to_owned(); + + if unsf { + after_code = format!("}}{after_code}"); } - .to_string() - .into() + + Cow::Owned(hoise_crate_attributes( + code, + &after_crate_attrs, + &after_code, + )) } /// Send a Discord reply with the formatted contents of a Playground result diff --git a/src/main.rs b/src/main.rs index 651ecc1..3140b3e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -86,8 +86,8 @@ async fn serenity(#[shuttle_runtime::Secrets] secret_store: SecretStore) -> Shut poise::Prefix::Literal("<:ferris:358652670585733120>"), poise::Prefix::Literal("<:ferrisballSweat:678714352450142239> "), poise::Prefix::Literal("<:ferrisballSweat:678714352450142239>"), - poise::Prefix::Literal("<:ferrisCat:678714352450142239> "), - poise::Prefix::Literal("<:ferrisCat:678714352450142239>"), + poise::Prefix::Literal("<:ferrisCat:1183779700485664820> "), + poise::Prefix::Literal("<:ferrisCat:1183779700485664820>"), poise::Prefix::Literal("<:ferrisOwO:579331467000283136> "), poise::Prefix::Literal("<:ferrisOwO:579331467000283136>"), poise::Prefix::Regex(