Skip to content

Commit 6674bb6

Browse files
authored
Merge pull request #16 from rage/remove-panics
Removed panics
2 parents f1311f5 + 133a759 commit 6674bb6

17 files changed

Lines changed: 651 additions & 753 deletions

src/commands.rs

Lines changed: 22 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -11,81 +11,68 @@ mod update;
1111
mod util;
1212

1313
use crate::io::{Io, PrintColor};
14+
use anyhow::Context;
1415
use util::{Client, ClientProduction};
1516

16-
pub fn handle(matches: &clap::ArgMatches, io: &mut dyn Io) {
17-
let mut client = ClientProduction::new(matches.is_present("testmode"));
17+
pub fn handle(matches: &clap::ArgMatches, io: &mut dyn Io) -> anyhow::Result<()> {
18+
let mut client = ClientProduction::new(matches.is_present("testmode"))?;
1819

1920
// Authorize the client and raise error if not logged in when required
2021
match matches.subcommand() {
2122
Some(("login", _)) => {
2223
if client.load_login().is_ok() {
23-
io.println(
24-
"Already logged in. Please logout first with 'tmc logout'",
25-
PrintColor::Failed,
26-
);
27-
return;
24+
anyhow::bail!("Already logged in. Please logout first with 'tmc logout'",);
2825
}
2926
}
3027
Some(("test", _)) => (),
3128
_ => {
32-
if client.load_login().is_err() {
33-
io.println(
34-
"No login found. Login to use this command with 'tmc login'",
35-
PrintColor::Failed,
36-
);
37-
return;
38-
}
29+
client
30+
.load_login()
31+
.context("No login found. Login to use this command with 'tmc login'")?;
3932
}
4033
};
4134

4235
// Check that organization is set
4336
if let Some(("download" | "courses", _)) = matches.subcommand() {
44-
if util::get_organization().is_none() {
45-
io.println(
46-
"No organization found. Run 'tmc organization' first.",
47-
PrintColor::Failed,
48-
);
49-
return;
50-
}
37+
util::get_organization().context("No organization found. Run 'tmc organization' first.")?;
5138
};
5239

5340
match matches.subcommand() {
5441
Some(("login", args)) => {
5542
let interactive_mode = !args.is_present("non-interactive");
56-
login::login(io, &mut client, interactive_mode)
43+
login::login(io, &mut client, interactive_mode)?;
5744
}
5845
Some(("download", args)) => download::download_or_update(
5946
io,
6047
&mut client,
6148
args.value_of("course"),
6249
args.is_present("currentdir"),
63-
),
50+
)?,
6451
Some(("update", args)) => {
65-
update::update(io, &mut client, args.is_present("currentdir"));
52+
update::update(io, &mut client, args.is_present("currentdir"))?;
6653
}
6754
Some(("organization", args)) => {
6855
let interactive_mode = !args.is_present("non-interactive");
69-
organization::organization(io, &mut client, interactive_mode)
56+
organization::organization(io, &mut client, interactive_mode)?
7057
}
71-
Some(("courses", _)) => courses::list_courses(io, &mut client),
58+
Some(("courses", _)) => courses::list_courses(io, &mut client)?,
7259
Some(("submit", args)) => {
73-
submit::submit(io, &mut client, args.value_of("exercise"));
60+
submit::submit(io, &mut client, args.value_of("exercise"))?;
7461
}
7562
Some(("exercises", args)) => {
7663
if let Some(c) = args.value_of("course") {
77-
exercises::list_exercises(io, &mut client, c);
64+
exercises::list_exercises(io, &mut client, c)?;
7865
} else {
79-
io.println("argument for course not found", PrintColor::Normal);
66+
io.println("argument for course not found", PrintColor::Normal)?;
8067
}
8168
}
8269
Some(("test", args)) => {
83-
test::test(io, args.value_of("exercise"));
70+
test::test(io, args.value_of("exercise"))?;
8471
}
8572
Some(("paste", args)) => {
86-
paste::paste(io, &mut client, args.value_of("exercise"));
73+
paste::paste(io, &mut client, args.value_of("exercise"))?;
8774
}
88-
Some(("logout", _)) => logout::logout(io, &mut client),
75+
Some(("logout", _)) => logout::logout(io, &mut client)?,
8976
Some(("fetchupdate", _)) => {
9077
#[cfg(target_os = "windows")]
9178
crate::updater::process_update();
@@ -95,11 +82,12 @@ pub fn handle(matches: &clap::ArgMatches, io: &mut dyn Io) {
9582
crate::updater::cleartemp().unwrap();
9683
}
9784
Some(("elevateddownload", _)) => {
98-
download::elevated_download(io, &mut client);
85+
download::elevated_download(io, &mut client)?;
9986
}
10087
Some(("elevatedupdate", _)) => {
101-
update::elevated_update(io, &mut client);
88+
update::elevated_update(io, &mut client)?;
10289
}
10390
_ => (), // Unknown subcommand or no subcommand was given
10491
}
92+
Ok(())
10593
}

src/commands/courses.rs

Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,19 @@ use crate::io::{Io, PrintColor};
33
use tmc_langs::Course;
44

55
/// Lists available courses from clients organization
6-
pub fn list_courses(io: &mut dyn Io, client: &mut dyn Client) {
7-
match client.list_courses() {
8-
Ok(course_list) => print_courses(io, course_list),
9-
Err(error) => io.println(&error, PrintColor::Failed),
10-
}
6+
pub fn list_courses(io: &mut dyn Io, client: &mut dyn Client) -> anyhow::Result<()> {
7+
let course_list = client.list_courses()?;
8+
print_courses(io, &course_list)?;
9+
Ok(())
1110
}
1211

1312
/// Prints course names
14-
fn print_courses(io: &mut dyn Io, course_list: Vec<Course>) {
15-
io.println("", PrintColor::Normal);
13+
fn print_courses(io: &mut dyn Io, course_list: &[Course]) -> anyhow::Result<()> {
14+
io.println("", PrintColor::Normal)?;
1615
for course in course_list {
17-
io.println(&course.name, PrintColor::Normal);
16+
io.println(&course.name, PrintColor::Normal)?;
1817
}
18+
Ok(())
1919
}
2020

2121
#[cfg(test)]
@@ -43,25 +43,27 @@ mod tests {
4343

4444
#[cfg(test)]
4545
impl Io for IoTest<'_> {
46-
fn read_line(&mut self) -> String {
47-
match self.input.next() {
46+
fn read_line(&mut self) -> anyhow::Result<String> {
47+
let res = match self.input.next() {
4848
Some(string) => string,
4949
None => "",
50-
}
51-
.to_string()
50+
};
51+
Ok(res.to_string())
5252
}
5353

54-
fn print(&mut self, output: &str, _font_color: PrintColor) {
54+
fn print(&mut self, output: &str, _font_color: PrintColor) -> anyhow::Result<()> {
5555
print!("{}", output);
5656
self.list.push(output.to_string());
57+
Ok(())
5758
}
5859

59-
fn println(&mut self, output: &str, _font_color: PrintColor) {
60+
fn println(&mut self, output: &str, _font_color: PrintColor) -> anyhow::Result<()> {
6061
println!("{}", output);
6162
self.list.push(output.to_string());
63+
Ok(())
6264
}
6365

64-
fn read_password(&mut self) -> String {
66+
fn read_password(&mut self) -> anyhow::Result<String> {
6567
self.read_line()
6668
}
6769
}
@@ -87,13 +89,13 @@ mod tests {
8789
fn is_test_mode(&mut self) -> bool {
8890
false
8991
}
90-
fn load_login(&mut self) -> Result<(), String> {
92+
fn load_login(&mut self) -> anyhow::Result<()> {
9193
Ok(())
9294
}
93-
fn try_login(&mut self, _username: String, _password: String) -> Result<String, String> {
95+
fn try_login(&mut self, _username: String, _password: String) -> anyhow::Result<String> {
9496
Ok("ok".to_string())
9597
}
96-
fn list_courses(&mut self) -> Result<Vec<Course>, String> {
98+
fn list_courses(&mut self) -> anyhow::Result<Vec<Course>> {
9799
Ok(vec![
98100
Course {
99101
id: 0,
@@ -119,10 +121,12 @@ mod tests {
119121
},
120122
])
121123
}
122-
fn get_organizations(&mut self) -> Result<Vec<Organization>, String> {
124+
fn get_organizations(&mut self) -> anyhow::Result<Vec<Organization>> {
123125
Ok(vec![])
124126
}
125-
fn logout(&mut self) {}
127+
fn logout(&mut self) -> anyhow::Result<()> {
128+
Ok(())
129+
}
126130
fn update_exercises(
127131
&mut self,
128132
_path: &Path,
@@ -172,14 +176,14 @@ mod tests {
172176
validations: None,
173177
})
174178
}
175-
fn get_course_exercises(&mut self, _course_id: u32) -> Result<Vec<CourseExercise>, String> {
179+
fn get_course_exercises(&mut self, _course_id: u32) -> anyhow::Result<Vec<CourseExercise>> {
176180
Ok(vec![])
177181
}
178182

179183
fn get_exercise_details(
180184
&mut self,
181185
_exercise_ids: Vec<u32>,
182-
) -> Result<Vec<ExercisesDetails>, String> {
186+
) -> Result<Vec<ExercisesDetails>, ClientError> {
183187
todo!()
184188
}
185189

@@ -217,7 +221,7 @@ mod tests {
217221
input: &mut input,
218222
};
219223

220-
let courses = vec![
224+
let courses = [
221225
Course {
222226
id: 0,
223227
name: "name".to_string(),
@@ -241,7 +245,7 @@ mod tests {
241245
spyware_urls: vec![],
242246
},
243247
];
244-
print_courses(&mut io, courses);
248+
print_courses(&mut io, &courses).unwrap();
245249

246250
assert!(io.list[0].eq(""));
247251
assert!(io.list[1].eq("name"), "Expected 'name', got {}", io.list[1]);
@@ -264,7 +268,7 @@ mod tests {
264268
};
265269

266270
let mut client = ClientTest {};
267-
list_courses(&mut io, &mut client);
271+
list_courses(&mut io, &mut client).unwrap();
268272

269273
assert!(io.list[0].eq(""), "first line should be empty");
270274
assert!(io.list[1].eq("name"), "Expected 'name', got {}", io.list[1]);

0 commit comments

Comments
 (0)