Skip to content

Commit 70e59cc

Browse files
committed
standardize exercise running via an external toml file
1 parent 7d6e281 commit 70e59cc

File tree

5 files changed

+267
-81
lines changed

5 files changed

+267
-81
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ indicatif = "0.9.0"
1010
console = "0.6.2"
1111
syntect = "3.0.2"
1212
notify = "4.0.0"
13+
toml = "0.4.10"

info.toml

Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
# VARIABLES
2+
3+
[[exercises]]
4+
path = "exercises/variables/variables1.rs"
5+
mode = "compile"
6+
7+
[[exercises]]
8+
path = "exercises/variables/variables2.rs"
9+
mode = "compile"
10+
11+
[[exercises]]
12+
path = "exercises/variables/variables3.rs"
13+
mode = "compile"
14+
15+
[[exercises]]
16+
path = "exercises/variables/variables4.rs"
17+
mode = "compile"
18+
19+
# IF
20+
21+
[[exercises]]
22+
path = "exercises/if/if1.rs"
23+
mode = "test"
24+
25+
# FUNCTIONS
26+
27+
[[exercises]]
28+
path = "exercises/functions/functions1.rs"
29+
mode = "compile"
30+
31+
[[exercises]]
32+
path = "exercises/functions/functions2.rs"
33+
mode = "compile"
34+
35+
[[exercises]]
36+
path = "exercises/functions/functions3.rs"
37+
mode = "compile"
38+
39+
[[exercises]]
40+
path = "exercises/functions/functions4.rs"
41+
mode = "compile"
42+
43+
[[exercises]]
44+
path = "exercises/functions/functions5.rs"
45+
mode = "compile"
46+
47+
# TEST 1
48+
49+
[[exercises]]
50+
path = "exercises/test1.rs"
51+
mode = "test"
52+
53+
# PRIMITIVE TYPES
54+
55+
[[exercises]]
56+
path = "exercises/primitive_types/primitive_types1.rs"
57+
mode = "compile"
58+
59+
[[exercises]]
60+
path = "exercises/primitive_types/primitive_types2.rs"
61+
mode = "compile"
62+
63+
[[exercises]]
64+
path = "exercises/primitive_types/primitive_types3.rs"
65+
mode = "compile"
66+
67+
[[exercises]]
68+
path = "exercises/primitive_types/primitive_types4.rs"
69+
mode = "compile"
70+
71+
[[exercises]]
72+
path = "exercises/primitive_types/primitive_types5.rs"
73+
mode = "compile"
74+
75+
[[exercises]]
76+
path = "exercises/primitive_types/primitive_types6.rs"
77+
mode = "compile"
78+
79+
# TESTS
80+
81+
[[exercises]]
82+
path = "exercises/tests/tests1.rs"
83+
mode = "test"
84+
85+
[[exercises]]
86+
path = "exercises/tests/tests2.rs"
87+
mode = "test"
88+
89+
[[exercises]]
90+
path = "exercises/tests/tests3.rs"
91+
mode = "test"
92+
93+
# TEST 2
94+
95+
[[exercises]]
96+
path = "exercises/test2.rs"
97+
mode = "test"
98+
99+
# STRINGS
100+
101+
[[exercises]]
102+
path = "exercises/strings/strings1.rs"
103+
mode = "compile"
104+
105+
[[exercises]]
106+
path = "exercises/strings/strings2.rs"
107+
mode = "compile"
108+
109+
# TEST 3
110+
111+
[[exercises]]
112+
path = "exercises/test3.rs"
113+
mode = "compile"
114+
115+
# MODULES
116+
117+
[[exercises]]
118+
path = "exercises/modules/modules1.rs"
119+
mode = "compile"
120+
121+
[[exercises]]
122+
path = "exercises/modules/modules2.rs"
123+
mode = "compile"
124+
125+
# MACROS
126+
127+
[[exercises]]
128+
path = "exercises/macros/macros1.rs"
129+
mode = "compile"
130+
131+
[[exercises]]
132+
path = "exercises/macros/macros2.rs"
133+
mode = "compile"
134+
135+
[[exercises]]
136+
path = "exercises/macros/macros3.rs"
137+
mode = "compile"
138+
139+
[[exercises]]
140+
path = "exercises/macros/macros4.rs"
141+
mode = "compile"
142+
143+
# TEST 4
144+
145+
[[exercises]]
146+
path = "exercises/test4.rs"
147+
mode = "compile"
148+
149+
# MOVE SEMANTICS
150+
151+
[[exercises]]
152+
path = "exercises/move_semantics/move_semantics1.rs"
153+
mode = "compile"
154+
155+
[[exercises]]
156+
path = "exercises/move_semantics/move_semantics2.rs"
157+
mode = "compile"
158+
159+
[[exercises]]
160+
path = "exercises/move_semantics/move_semantics3.rs"
161+
mode = "compile"
162+
163+
[[exercises]]
164+
path = "exercises/move_semantics/move_semantics4.rs"
165+
mode = "compile"
166+
167+
# ERROR HANDLING
168+
169+
[[exercises]]
170+
path = "exercises/error_handling/errors1.rs"
171+
mode = "test"
172+
173+
[[exercises]]
174+
path = "exercises/error_handling/errors2.rs"
175+
mode = "test"
176+
177+
[[exercises]]
178+
path = "exercises/error_handling/errors3.rs"
179+
mode = "test"
180+
181+
[[exercises]]
182+
path = "exercises/error_handling/errorsn.rs"
183+
mode = "test"
184+
185+
# OPTIONS / RESULTS
186+
187+
[[exercises]]
188+
path = "exercises/error_handling/option1.rs"
189+
mode = "compile"
190+
191+
[[exercises]]
192+
path = "exercises/error_handling/result1.rs"
193+
mode = "test"
194+
195+
# THREADS
196+
197+
[[exercises]]
198+
path = "exercises/threads/threads1.rs"
199+
mode = "compile"

src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ fn main() {
4848
}
4949

5050
if let Some(matches) = matches.subcommand_matches("run") {
51-
run(matches.clone());
51+
run(matches.clone()).unwrap();
5252
}
5353

5454
if let Some(_) = matches.subcommand_matches("verify") {

src/run.rs

Lines changed: 55 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -2,54 +2,71 @@ use crate::util::clean;
22
use crate::verify::test;
33
use console::{style, Emoji};
44
use indicatif::ProgressBar;
5+
use std::fs;
56
use std::process::Command;
7+
use toml::Value;
68

7-
pub fn run(matches: clap::ArgMatches) {
9+
pub fn run(matches: clap::ArgMatches) -> Result<(), ()> {
810
if let Some(filename) = matches.value_of("file") {
9-
if matches.is_present("test") {
10-
match test(filename) {
11-
Ok(_) => (),
12-
Err(_) => (),
13-
}
14-
std::process::exit(0);
11+
let toml: Value = fs::read_to_string("info.toml").unwrap().parse().unwrap();
12+
let tomlvec: &Vec<Value> = toml.get("exercises").unwrap().as_array().unwrap();
13+
let mut exercises = tomlvec.clone();
14+
exercises.retain(|i| i.get("path").unwrap().as_str().unwrap() == filename);
15+
if exercises.is_empty() {
16+
println!("No exercise found for your filename!");
17+
std::process::exit(1);
1518
}
16-
let bar = ProgressBar::new_spinner();
17-
bar.set_message(format!("Compiling {}...", filename).as_str());
18-
bar.enable_steady_tick(100);
19-
let compilecmd = Command::new("rustc")
20-
.args(&[filename, "-o", "temp", "--color", "always"])
21-
.output()
22-
.expect("fail");
23-
bar.set_message(format!("Running {}...", filename).as_str());
24-
if compilecmd.status.success() {
25-
let runcmd = Command::new("./temp").output().expect("fail");
26-
bar.finish_and_clear();
2719

28-
if runcmd.status.success() {
29-
println!("{}", String::from_utf8_lossy(&runcmd.stdout));
30-
let formatstr = format!("{} Successfully ran {}", Emoji("✅", "✓"), filename);
31-
println!("{}", style(formatstr).green());
32-
clean();
33-
} else {
34-
println!("{}", String::from_utf8_lossy(&runcmd.stdout));
35-
println!("{}", String::from_utf8_lossy(&runcmd.stderr));
20+
let exercise: &Value = &exercises[0];
21+
match exercise.get("mode").unwrap().as_str().unwrap() {
22+
"test" => test(exercise.get("path").unwrap().as_str().unwrap())?,
23+
"compile" => compile_and_run(exercise.get("path").unwrap().as_str().unwrap())?,
24+
_ => (),
25+
}
26+
Ok(())
27+
} else {
28+
panic!("Please supply a filename!");
29+
}
30+
}
3631

37-
let formatstr = format!("{} Ran {} with errors", Emoji("⚠️ ", "!"), filename);
38-
println!("{}", style(formatstr).red());
39-
clean();
40-
}
32+
pub fn compile_and_run(filename: &str) -> Result<(), ()> {
33+
let bar = ProgressBar::new_spinner();
34+
bar.set_message(format!("Compiling {}...", filename).as_str());
35+
bar.enable_steady_tick(100);
36+
let compilecmd = Command::new("rustc")
37+
.args(&[filename, "-o", "temp", "--color", "always"])
38+
.output()
39+
.expect("fail");
40+
bar.set_message(format!("Running {}...", filename).as_str());
41+
if compilecmd.status.success() {
42+
let runcmd = Command::new("./temp").output().expect("fail");
43+
bar.finish_and_clear();
44+
45+
if runcmd.status.success() {
46+
println!("{}", String::from_utf8_lossy(&runcmd.stdout));
47+
let formatstr = format!("{} Successfully ran {}", Emoji("✅", "✓"), filename);
48+
println!("{}", style(formatstr).green());
49+
clean();
50+
Ok(())
4151
} else {
42-
bar.finish_and_clear();
43-
let formatstr = format!(
44-
"{} Compilation of {} failed! Compiler error message:\n",
45-
Emoji("⚠️ ", "!"),
46-
filename
47-
);
52+
println!("{}", String::from_utf8_lossy(&runcmd.stdout));
53+
println!("{}", String::from_utf8_lossy(&runcmd.stderr));
54+
55+
let formatstr = format!("{} Ran {} with errors", Emoji("⚠️ ", "!"), filename);
4856
println!("{}", style(formatstr).red());
49-
println!("{}", String::from_utf8_lossy(&compilecmd.stderr));
5057
clean();
58+
Err(())
5159
}
5260
} else {
53-
panic!("Please supply a filename!");
61+
bar.finish_and_clear();
62+
let formatstr = format!(
63+
"{} Compilation of {} failed! Compiler error message:\n",
64+
Emoji("⚠️ ", "!"),
65+
filename
66+
);
67+
println!("{}", style(formatstr).red());
68+
println!("{}", String::from_utf8_lossy(&compilecmd.stderr));
69+
clean();
70+
Err(())
5471
}
5572
}

src/verify.rs

Lines changed: 11 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,20 @@
11
use crate::util::clean;
22
use console::{style, Emoji};
33
use indicatif::ProgressBar;
4+
use std::fs;
45
use std::process::Command;
6+
use toml::Value;
57

68
pub fn verify() -> Result<(), ()> {
7-
compile_only("exercises/variables/variables1.rs")?;
8-
compile_only("exercises/variables/variables2.rs")?;
9-
compile_only("exercises/variables/variables3.rs")?;
10-
compile_only("exercises/variables/variables4.rs")?;
11-
test("exercises/if/if1.rs")?;
12-
compile_only("exercises/functions/functions1.rs")?;
13-
compile_only("exercises/functions/functions2.rs")?;
14-
compile_only("exercises/functions/functions3.rs")?;
15-
compile_only("exercises/functions/functions4.rs")?;
16-
compile_only("exercises/functions/functions5.rs")?;
17-
test("exercises/test1.rs")?;
18-
compile_only("exercises/primitive_types/primitive_types1.rs")?;
19-
compile_only("exercises/primitive_types/primitive_types2.rs")?;
20-
compile_only("exercises/primitive_types/primitive_types3.rs")?;
21-
compile_only("exercises/primitive_types/primitive_types4.rs")?;
22-
compile_only("exercises/primitive_types/primitive_types5.rs")?;
23-
compile_only("exercises/primitive_types/primitive_types6.rs")?;
24-
test("exercises/tests/tests1.rs")?;
25-
test("exercises/tests/tests2.rs")?;
26-
test("exercises/tests/tests3.rs")?;
27-
test("exercises/test2.rs")?;
28-
compile_only("exercises/strings/strings1.rs")?;
29-
compile_only("exercises/strings/strings2.rs")?;
30-
compile_only("exercises/test3.rs")?;
31-
compile_only("exercises/modules/modules1.rs")?;
32-
compile_only("exercises/modules/modules2.rs")?;
33-
compile_only("exercises/macros/macros1.rs")?;
34-
compile_only("exercises/macros/macros2.rs")?;
35-
compile_only("exercises/macros/macros3.rs")?;
36-
compile_only("exercises/macros/macros4.rs")?;
37-
compile_only("exercises/test4.rs")?;
38-
compile_only("exercises/move_semantics/move_semantics1.rs")?;
39-
compile_only("exercises/move_semantics/move_semantics2.rs")?;
40-
compile_only("exercises/move_semantics/move_semantics3.rs")?;
41-
compile_only("exercises/move_semantics/move_semantics4.rs")?;
42-
test("exercises/error_handling/errors1.rs")?;
43-
test("exercises/error_handling/errors2.rs")?;
44-
test("exercises/error_handling/errors3.rs")?;
45-
test("exercises/error_handling/errorsn.rs")?;
46-
compile_only("exercises/error_handling/option1.rs")?;
47-
test("exercises/error_handling/result1.rs")?;
48-
compile_only("exercises/threads/threads1.rs")?;
9+
let toml: Value = fs::read_to_string("info.toml").unwrap().parse().unwrap();
10+
let tomlvec: &Vec<Value> = toml.get("exercises").unwrap().as_array().unwrap();
11+
for i in tomlvec {
12+
match i.get("mode").unwrap().as_str().unwrap() {
13+
"test" => test(i.get("path").unwrap().as_str().unwrap())?,
14+
"compile" => compile_only(i.get("path").unwrap().as_str().unwrap())?,
15+
_ => (),
16+
}
17+
}
4918
Ok(())
5019
}
5120

0 commit comments

Comments
 (0)