This repository has been archived on 2024-05-23. You can view files and clone it, but cannot push or open issues or pull requests.
cal8tor/src/filter.rs

141 lines
4.2 KiB
Rust
Raw Normal View History

2023-09-28 23:16:39 +02:00
use std::collections::HashMap;
use dialoguer::MultiSelect;
use crate::timetable::models::Category;
2023-09-28 23:16:39 +02:00
use crate::timetable::models::Course;
use crate::timetable::models::Timetable;
2023-09-29 00:03:45 +02:00
use crate::utils::fill_hours;
2023-09-28 23:16:39 +02:00
const DISCLAIMER: &str = "(selection avec ESPACE, ENTRER pour valider)";
/// Filter the timetable
pub fn timetable(timetable: Timetable) -> Timetable {
let mut my_timetable = timetable;
2023-09-29 00:03:45 +02:00
courses(&mut my_timetable);
2023-09-28 23:16:39 +02:00
tdtp(&mut my_timetable);
my_timetable
}
/// Exclude some courses
fn courses(timetable: &mut Timetable) {
let mut multiselected = vec![];
timetable.1 .1.iter().for_each(|day| {
day.courses.iter().for_each(|course_opt| {
if let Some(course) = course_opt {
if !multiselected.contains(&course.name) {
multiselected.push(course.name.to_owned());
}
}
})
});
let defaults = vec![true; multiselected.len()];
let selections = MultiSelect::new()
.with_prompt(format!("Choisis tes matières {}", DISCLAIMER))
.items(&multiselected[..])
.defaults(&defaults[..])
.interact()
.unwrap();
for day in &mut timetable.1 .1 {
day.courses.retain(|course_opt| {
if let Some(course) = course_opt {
// Remove courses not followed
for i in &selections {
if course.name == multiselected[*i] {
return true;
}
}
}
false
});
}
}
/// Filter the multiples TD/TP
fn tdtp(timetable: &mut Timetable) {
2023-09-29 00:03:45 +02:00
// Entry's name used for finding duplicates
let get_entry = |course: &Course| format!("{} - {:?}", course.name, course.category);
2023-09-29 00:03:45 +02:00
let mut hours = vec![];
fill_hours(&mut hours);
// Names showed to the users
let get_selection = |data: &(&Course, String)| {
format!(
"{} - {} {}-{}",
data.0.name,
data.1,
hours[data.0.start].split_once('-').unwrap().0,
hours[data.0.start + data.0.size - 1]
.split_once('-')
.unwrap()
.1
)
};
// List of courses who will be TP/TD
2023-09-28 23:16:39 +02:00
let mut td_or_tp = vec![];
2023-09-29 00:03:45 +02:00
// Counter of appearing of TP/TD to know if a TP/TD have multiple possible course
2023-09-28 23:16:39 +02:00
let mut counts = HashMap::new();
timetable.1 .1.iter().for_each(|day| {
day.courses.iter().for_each(|course_opt| {
if let Some(course) = course_opt {
match course.category {
Category::TD | Category::TP => {
2023-09-29 00:03:45 +02:00
td_or_tp.push((course, day.name.to_owned()));
2023-09-28 23:16:39 +02:00
let count = counts.entry(get_entry(course)).or_insert(0);
*count += 1;
}
_ => (),
}
}
})
});
2023-09-29 00:03:45 +02:00
2023-09-28 23:16:39 +02:00
// Keep only elements who have multiples TD/TP
2023-09-29 00:03:45 +02:00
td_or_tp.retain(|course| *counts.get(&get_entry(course.0)).unwrap() > 1);
2023-09-28 23:16:39 +02:00
2023-09-29 00:03:45 +02:00
let mut multiselected: Vec<String> = td_or_tp.iter().map(|el| get_selection(el)).collect();
multiselected.sort();
2023-09-28 23:16:39 +02:00
let defaults = vec![false; multiselected.len()];
2023-09-28 23:16:39 +02:00
let selections = MultiSelect::new()
.with_prompt(format!("Choisis tes horaires de TD/TP {}", DISCLAIMER))
.items(&multiselected[..])
.defaults(&defaults[..])
.interact()
.unwrap();
2023-09-29 00:03:45 +02:00
// Keep only wanted courses
2023-09-28 23:16:39 +02:00
for day in &mut timetable.1 .1 {
day.courses.retain(|course_opt| {
if let Some(course) = course_opt {
2023-09-29 00:03:45 +02:00
// Keep if it's a course
if course.category == Category::Cours {
2023-09-29 00:03:45 +02:00
return true;
}
// Keep if its an -only one course- TD/TP
if *counts.get(&get_entry(course)).unwrap() == 1 {
return true;
}
2023-09-28 23:16:39 +02:00
// Remove courses not followed
for i in &selections {
2023-09-29 00:03:45 +02:00
if get_selection(&(course, day.name.to_owned())) == multiselected[*i] {
2023-09-28 23:16:39 +02:00
return true;
}
}
}
false
});
}
}