@@ -8,20 +8,21 @@ use crate::{
88use reqwest:: header;
99use serde:: { Deserialize , Serialize } ;
1010use std:: collections:: HashMap ;
11+ use std:: str:: FromStr ;
1112
1213#[ derive( Debug , Serialize ) ]
13- struct PlaygroundCode {
14+ struct PlaygroundCode < ' a > {
1415 channel : Channel ,
1516 edition : Edition ,
16- code : String ,
17+ code : & ' a str ,
1718 #[ serde( rename = "crateType" ) ]
1819 crate_type : CrateType ,
1920 mode : Mode ,
2021 tests : bool ,
2122}
2223
23- impl PlaygroundCode {
24- fn new ( code : String ) -> Self {
24+ impl < ' a > PlaygroundCode < ' a > {
25+ fn new ( code : & ' a str ) -> Self {
2526 PlaygroundCode {
2627 channel : Channel :: Nightly ,
2728 edition : Edition :: E2018 ,
@@ -64,6 +65,19 @@ enum Channel {
6465 Nightly ,
6566}
6667
68+ impl FromStr for Channel {
69+ type Err = Box < dyn std:: error:: Error > ;
70+
71+ fn from_str ( s : & str ) -> Result < Self > {
72+ match s {
73+ "stable" => Ok ( Channel :: Stable ) ,
74+ "beta" => Ok ( Channel :: Beta ) ,
75+ "nightly" => Ok ( Channel :: Nightly ) ,
76+ _ => Err ( format ! ( "invalid release channel `{}`" , s) . into ( ) ) ,
77+ }
78+ }
79+ }
80+
6781#[ derive( Debug , Serialize ) ]
6882enum Edition {
6983 #[ serde( rename = "2015" ) ]
@@ -72,6 +86,18 @@ enum Edition {
7286 E2018 ,
7387}
7488
89+ impl FromStr for Edition {
90+ type Err = Box < dyn std:: error:: Error > ;
91+
92+ fn from_str ( s : & str ) -> Result < Self > {
93+ match s {
94+ "2015" => Ok ( Edition :: E2015 ) ,
95+ "2018" => Ok ( Edition :: E2018 ) ,
96+ _ => Err ( format ! ( "invalid edition `{}`" , s) . into ( ) ) ,
97+ }
98+ }
99+ }
100+
75101#[ derive( Debug , Serialize ) ]
76102enum CrateType {
77103 #[ serde( rename = "bin" ) ]
@@ -87,6 +113,18 @@ enum Mode {
87113 Release ,
88114}
89115
116+ impl FromStr for Mode {
117+ type Err = Box < dyn std:: error:: Error > ;
118+
119+ fn from_str ( s : & str ) -> Result < Self > {
120+ match s {
121+ "debug" => Ok ( Mode :: Debug ) ,
122+ "release" => Ok ( Mode :: Release ) ,
123+ _ => Err ( format ! ( "invalid compilation mode `{}`" , s) . into ( ) ) ,
124+ }
125+ }
126+ }
127+
90128#[ derive( Debug , Deserialize ) ]
91129struct PlayResult {
92130 success : bool ,
@@ -95,8 +133,32 @@ struct PlayResult {
95133}
96134
97135fn run_code ( args : & Args , code : & str ) -> Result < String > {
98- info ! ( "sending request to playground." ) ;
99- let request = PlaygroundCode :: new ( code. to_string ( ) ) ;
136+ let mut errors = String :: new ( ) ;
137+
138+ let channel = args. params . get ( "channel" ) . unwrap_or_else ( || & "nightly" ) ;
139+ let mode = args. params . get ( "mode" ) . unwrap_or_else ( || & "debug" ) ;
140+ let edition = args. params . get ( "edition" ) . unwrap_or_else ( || & "2018" ) ;
141+
142+ let mut request = PlaygroundCode :: new ( code) ;
143+
144+ match Channel :: from_str ( channel) {
145+ Ok ( c) => request. channel = c,
146+ Err ( e) => errors += & format ! ( "{}\n " , e) ,
147+ }
148+
149+ match Mode :: from_str ( mode) {
150+ Ok ( m) => request. mode = m,
151+ Err ( e) => errors += & format ! ( "{}\n " , e) ,
152+ }
153+
154+ match Edition :: from_str ( edition) {
155+ Ok ( e) => request. edition = e,
156+ Err ( e) => errors += & format ! ( "{}\n " , e) ,
157+ }
158+
159+ if !code. contains ( "fn main" ) {
160+ request. crate_type = CrateType :: Library ;
161+ }
100162
101163 let resp = args
102164 . http
@@ -112,13 +174,16 @@ fn run_code(args: &Args, code: &str) -> Result<String> {
112174 result. stderr
113175 } ;
114176
115- Ok ( if result. len ( ) > 1994 {
177+ Ok ( if result. len ( ) + errors . len ( ) > 1994 {
116178 format ! (
117- "Output too large. Playground link: {}" ,
179+ "{}Output too large. Playground link: {}" ,
180+ errors,
118181 get_playground_link( args, code, & request) ?
119182 )
183+ } else if result. len ( ) == 0 {
184+ format ! ( "{}compilation succeded." , errors)
120185 } else {
121- format ! ( "```{}```" , result)
186+ format ! ( "{} ```{}```" , errors , result)
122187 } )
123188}
124189
@@ -134,11 +199,11 @@ fn get_playground_link(args: &Args, code: &str, request: &PlaygroundCode) -> Res
134199 . send ( ) ?;
135200
136201 let resp: HashMap < String , String > = resp. json ( ) ?;
137- debug ! ( "gist response: {:?}" , resp) ;
202+ info ! ( "gist response: {:?}" , resp) ;
138203
139204 resp. get ( "id" )
140205 . map ( |id| request. url_from_gist ( id) )
141- . ok_or ( "no gist found" . into ( ) )
206+ . ok_or_else ( || "no gist found" . into ( ) )
142207}
143208
144209pub fn run ( args : Args ) -> Result < ( ) > {
@@ -152,7 +217,23 @@ pub fn run(args: Args) -> Result<()> {
152217 Ok ( ( ) )
153218}
154219
155- pub fn help ( args : Args ) -> Result < ( ) > {
220+ pub fn help ( args : Args , name : & str ) -> Result < ( ) > {
221+ let message = format ! (
222+ "Compile and run rust code. All code is executed on https://play.rust-lang.org.
223+ ```?{} mode={{}} channel={{}} edition={{}} ``\u{200B} `code``\u{200B} ` ```
224+ Optional arguments:
225+ \t mode: debug, release (default: debug)
226+ \t channel: stable, beta, nightly (default: nightly)
227+ \t edition: 2015, 2018 (default: 2018)
228+ " ,
229+ name
230+ ) ;
231+
232+ api:: send_reply ( & args, & message) ?;
233+ Ok ( ( ) )
234+ }
235+
236+ pub fn err ( args : Args ) -> Result < ( ) > {
156237 let message = "Missing code block. Please use the following markdown:
157238\\ `\\ `\\ `rust
158239 code here
@@ -183,7 +264,7 @@ pub fn eval(args: Args) -> Result<()> {
183264 Ok ( ( ) )
184265}
185266
186- pub fn eval_help ( args : Args ) -> Result < ( ) > {
267+ pub fn eval_err ( args : Args ) -> Result < ( ) > {
187268 let message = "Missing code block. Please use the following markdown:
188269 \\ `code here\\ `
189270 or
0 commit comments