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 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}