code_runner/
lib.rs

1use serde_json;
2use serde_json::Value;
3use std::fs;
4use std::process::{Command, Stdio};
5use std::io::prelude::*;
6
7use serde::{Serialize, Deserialize};
8
9#[derive(Debug)]
10pub struct Input<'a> {
11    filename: &'a str,
12    input_file: String,
13    cmd_params: CmdParam,
14}
15
16#[derive(Debug)]
17pub struct Runner {
18    stdout: String,
19    stderr: String,
20}
21pub trait Spawn {
22    fn run(&self) -> Runner;
23    fn run_compiled(&self) -> Runner;
24    fn run_interpreted(&self) -> Runner;
25}
26impl<'a> Spawn for Input<'a> {
27    fn run(&self) -> Runner {
28        let result: Runner;
29        if self.cmd_params.file_type == 1 {
30            result = Spawn::run_interpreted(self);
31        } else {
32            result = Spawn::run_compiled(self);
33        }
34        result
35    }
36
37    fn run_compiled(&self) -> Runner {
38        let filepath = self.filename;
39        let arg_vec = self.cmd_params.command.clone();
40        let mut new_arg: Vec<String> = Vec::new();
41        {
42            for index in 0..arg_vec.len() {
43                let arg = &arg_vec[index];
44                if arg == "file_path" {
45                    new_arg.push(String::from("src/temp/") + self.filename.clone());
46                } else {
47                    new_arg.push(arg.to_string());
48                }
49             }
50        }
51        let file_path = &(String::from("src/temp/") + &filepath + &self.cmd_params.lang_ext);
52        new_arg.push(file_path.to_string());
53        
54        let compile = Command::new(self.cmd_params.default_path.clone())
55            .args(&new_arg)            
56            .output()
57            .expect("fail to build");
58        let mut s = String::from("out");
59        // println!("Hey {:?}", compile.stderr);
60        if compile.stderr.len() == 0 {
61            let execute = match Command::new(&(String::from("src/temp/") + &filepath))
62                .stdin(Stdio::piped())
63                .stdout(Stdio::piped())
64                .spawn() {
65                    Err(why) => panic!("couldn't spawn wc: {:?}", why),
66                    Ok(process) => process,
67                };
68            match execute.stdin.unwrap().write_all(&fs::read(self.input_file.clone()).unwrap()) {
69                Err(why) => panic!("couldn't write to wc stdin: {:?}", why),
70                Ok(_) => println!("sent pangram to wc"),
71            }
72            s = String::new();
73            match execute.stdout.unwrap().read_to_string(&mut s) {
74                Err(why) => panic!("couldn't read wc stdout: {:?}",why),
75                Ok(_) => (),
76            }
77        }
78        
79        match cleanup_file(filepath, &self.cmd_params.lang_ext, self.cmd_params.file_type) {
80            Ok(_) => (),
81            Err(e) => panic!("Hey {:?}", e),
82        };
83        Runner {
84            stdout: s,
85            stderr: String::from("err"),
86        }
87    }
88    fn run_interpreted(&self) -> Runner {
89        let filepath = self.filename;
90        println!("{}", filepath);
91        let execute = match Command::new(self.cmd_params.default_path.clone())
92            .arg(String::from("src/temp/") + &filepath + &self.cmd_params.lang_ext)
93            .stdin(Stdio::piped())
94            .stdout(Stdio::piped())
95            .spawn() {
96                Err(why) => panic!("couldn't spawn wc: {:?}", why),
97                Ok(process) => process,
98            };
99        match execute.stdin.unwrap().write_all(&fs::read(self.input_file.clone()).unwrap()) {
100            Err(why) => panic!("couldn't write to wc stdin: {:?}", why),
101            Ok(_) => println!("sent pangram to wc"),
102        }
103        let mut s = String::new();
104        match execute.stdout.unwrap().read_to_string(&mut s) {
105            Err(why) => panic!("couldn't read wc stdout: {:?}",why),
106            Ok(_) => (),
107         }
108        
109        match cleanup_file(filepath, &self.cmd_params.lang_ext, self.cmd_params.file_type) {
110            Ok(_) => (),
111            Err(e) => panic!("Hey {:?}", e),
112        };
113        Runner {
114            stdout: s,
115            stderr: String::from("err"),
116        }
117    }
118}
119
120#[derive(Debug)]
121pub struct ClientReq<'r> {
122    code_file: Vec<u8>,
123    file_type: &'r str,
124    input_file: Vec<Vec<u8>>,
125}
126
127pub fn create_spawn(req: ClientReq) {
128    file_runner_command(req.file_type);
129}
130
131#[warn(dead_code)]
132fn save_to_temp(file: Vec<u8>, name: String) {
133    match fs::write(name, file) {
134        Ok(_) => (),
135        Err(e) => panic!(e),
136    }
137}
138#[derive(Serialize, Deserialize, Debug)]
139struct CmdParam {
140    command: Vec<String>,
141    default_path: String,
142    #[serde(rename = "type")]
143    file_type: u8,
144    lang_ext: String,
145}
146
147#[warn(dead_code)]
148fn file_runner_command(ext: &str) -> CmdParam {
149    let json_cont = match fs::read_to_string("config/lang.json") {
150        Ok(v) => v,
151        Err(e) => panic!("JSON FILE:: {:?}", e),
152    };
153    let data: Value = serde_json::from_str(&json_cont[..]).unwrap();
154    let data1 = data.get(ext).unwrap();
155    let params: CmdParam = serde_json::from_value(data1.clone()).unwrap();
156    params
157}
158
159fn cleanup_file(filepath: &str, extension: &str, file_type: u8) -> std::io::Result<()> {
160    if file_type == 1 {
161        fs::remove_file(String::from("src/temp/") + &filepath + extension)?;
162    } else {
163        fs::remove_file(String::from("src/temp/") + &filepath)?;
164        fs::remove_file(String::from("src/temp/") + &filepath + extension)?;
165    }
166    Ok(())
167}
168
169#[cfg(test)]
170mod test {
171    use super::*;
172    use std::fs;
173    use uuid::Uuid;
174    #[test]
175    fn py_run() {
176        let cont = fs::read("src/temp/hello.py").unwrap();
177        let filename: String = Uuid::new_v4().to_string();
178        let ext: &str = "py2";
179        let cmd_params: CmdParam = file_runner_command(ext);
180        let input_filename = String::from("src/temp/input.in");
181        save_to_temp(
182            cont,
183            String::from("src/temp/") + &filename.clone() + &cmd_params.lang_ext,
184        );
185        let input: &Input = &Input {
186            filename: &filename,
187            cmd_params: cmd_params,
188            input_file: input_filename,
189        };
190        let result: Runner = Spawn::run(input);
191        println!("hey {:?}", result);
192    }
193    #[test]
194    fn c_run() {
195        let cont = fs::read("src/temp/hello.c").unwrap();
196        let filename: String = Uuid::new_v4().to_string();
197        let ext: &str = "c";
198        let cmd_params: CmdParam = file_runner_command(ext);
199        let input_filename = String::from("src/temp/input.in");
200        save_to_temp(
201            cont,
202            String::from("src/temp/") + &filename.clone() + &cmd_params.lang_ext,
203        );
204
205        let input: &Input = &Input {
206            filename: &filename,
207            cmd_params: cmd_params,
208            input_file: input_filename,
209        };
210        let result: Runner = Spawn::run(input);
211        println!("hey {:?}", result);
212    }
213    #[test]
214    fn go_run() {
215
216    }
217}