Skip to content

Commit

Permalink
Add commands to list courses and lesson matching the current filter (#9)
Browse files Browse the repository at this point in the history
  • Loading branch information
martinmr authored Jul 13, 2022
1 parent 61da9fb commit cd5a7d6
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 9 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ chrono = "0.4.19"
clap = { version = "3.2.10", features = ["derive"] }
rustyline = "9.1.2"
termimad = "0.20.2"
trane = "0.2.5"
trane = "0.2.6"

# Commented out for use in local development.
# trane = { path = "../trane" }
101 changes: 101 additions & 0 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,7 @@ impl TraneApp {
Ok(())
}

/// Lists the IDs of all the courses in the library.
pub fn list_courses(&self) -> Result<()> {
ensure!(self.trane.is_some(), "no Trane instance is open");

Expand All @@ -344,6 +345,7 @@ impl TraneApp {
Ok(())
}

/// Lists the IDs of all the exercises in the given lesson.
pub fn list_exercises(&self, lesson_id: &str) -> Result<()> {
ensure!(self.trane.is_some(), "no Trane instance is open");

Expand All @@ -361,6 +363,7 @@ impl TraneApp {
Ok(())
}

/// Lists the IDs of all the lessons in the given course.
pub fn list_lessons(&self, course_id: &str) -> Result<()> {
ensure!(self.trane.is_some(), "no Trane instance is open");

Expand All @@ -378,6 +381,104 @@ impl TraneApp {
Ok(())
}

/// Lists all the courses which match the current filter.
pub fn list_matching_courses(&self) -> Result<()> {
ensure!(self.trane.is_some(), "no Trane instance is open");

let courses: Vec<String> = self
.trane
.as_ref()
.unwrap()
.get_course_ids()
.into_iter()
.filter(|course_id| {
if self.filter.is_none() {
return true;
}

let filter = self.filter.as_ref().unwrap();
let manifest = self.trane.as_ref().unwrap().get_course_manifest(course_id);
match manifest {
Some(manifest) => match filter {
UnitFilter::CourseFilter { .. } => filter.apply_course_id(course_id),
UnitFilter::LessonFilter { .. } => false,
UnitFilter::MetadataFilter { .. } => {
filter.apply_course_metadata(&manifest)
}
},
None => false,
}
})
.collect();

if courses.is_empty() {
println!("No matching courses");
return Ok(());
}

println!("Matching courses:");
println!();
for course in courses {
println!("{}", course);
}
Ok(())
}

/// Lists all the lessons in the given course which match the current filter.
pub fn list_matching_lessons(&self, course_id: &str) -> Result<()> {
ensure!(self.trane.is_some(), "no Trane instance is open");

let lessons: Vec<String> = self
.trane
.as_ref()
.unwrap()
.get_lesson_ids(course_id)?
.into_iter()
.filter(|lesson_id| {
if self.filter.is_none() {
return true;
}

let filter = self.filter.as_ref().unwrap();
let lesson_manifest = self.trane.as_ref().unwrap().get_lesson_manifest(lesson_id);
match lesson_manifest {
Some(lesson_manifest) => match filter {
UnitFilter::CourseFilter { .. } => {
filter.apply_course_id(&lesson_manifest.course_id)
}
UnitFilter::LessonFilter { .. } => filter.apply_lesson_id(lesson_id),
UnitFilter::MetadataFilter { .. } => {
let course_manifest = self
.trane
.as_ref()
.unwrap()
.get_course_manifest(&lesson_manifest.course_id);
if course_manifest.is_none() {
// This should never happen but print the lesson ID if it does.
return true;
}
let course_manifest = course_manifest.unwrap();
filter.apply_lesson_metadata(&lesson_manifest, &course_manifest)
}
},
None => false,
}
})
.collect();

if lessons.is_empty() {
println!("No matching lessons in course {}", course_id);
return Ok(());
}

println!("Lessons:");
println!();
for lesson in lessons {
println!("{}", lesson);
}
Ok(())
}

/// Displays the next exercise.
pub fn next(&mut self) -> Result<()> {
ensure!(self.trane.is_some(), "no Trane instance is open");
Expand Down
28 changes: 22 additions & 6 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,17 +170,27 @@ pub(crate) enum ListSubcommands {
#[clap(about = "Show the IDs of all courses in the library")]
Courses,

#[clap(about = "Show the IDs of all exercises in the given lesson")]
Exercises {
#[clap(help = "The ID of the lesson")]
lesson_id: String,
},

#[clap(about = "Show the IDs of all lessons in the given course")]
Lessons {
#[clap(help = "The ID of the course")]
course_id: String,
},

#[clap(about = "Show the IDs of all exercises in the given lesson")]
Exercises {
#[clap(help = "The ID of the lesson")]
lesson_id: String,
#[clap(about = "Show the IDs of all the lessons in the given course \
which match the current filter")]
MatchingLessons {
#[clap(help = "The ID of the course")]
course_id: String,
},

#[clap(about = "Show the IDs of all the courses which match the current filter")]
MatchingCourses,
}

/// Contains subcommands used for displaying course and lesson materials.
Expand Down Expand Up @@ -397,12 +407,18 @@ impl TraneCli {

Subcommands::List(ListSubcommands::Courses) => app.list_courses(),

Subcommands::List(ListSubcommands::Exercises { lesson_id }) => {
app.list_exercises(lesson_id)
}

Subcommands::List(ListSubcommands::Lessons { course_id }) => {
app.list_lessons(course_id)
}

Subcommands::List(ListSubcommands::Exercises { lesson_id }) => {
app.list_exercises(lesson_id)
Subcommands::List(ListSubcommands::MatchingCourses) => app.list_matching_courses(),

Subcommands::List(ListSubcommands::MatchingLessons { course_id }) => {
app.list_matching_lessons(course_id)
}

Subcommands::Material(MaterialSubcommands::Course { course_id }) => {
Expand Down

0 comments on commit cd5a7d6

Please sign in to comment.