use std::borrow::Borrow;
use crate::{filter::student::StudentFilterOptions, types::Student, BlueArchiveError, Language};
use anyhow::Result;
use rand::seq::SliceRandom;
#[derive(Debug, Clone)]
pub struct StudentFetcher {
pub students: Vec<Student>,
}
impl StudentFetcher {
pub async fn new(language: impl Borrow<Language>) -> Result<Self, BlueArchiveError> {
Ok(Self {
students: crate::fetch_all_students(language).await?,
})
}
#[cfg(feature = "blocking")]
pub fn new_blocking(language: impl Borrow<Language>) -> Result<Self, BlueArchiveError> {
Ok(Self {
students: crate::blocking::get_all_students(language)?,
})
}
pub fn get_student_by_name(&self, name: impl AsRef<str>) -> Option<&Student> {
let mut matched_student = None;
for student in &self.students {
let lowercased = name.as_ref().to_lowercase();
let maybe_student = (lowercased == student.name.to_lowercase()
|| lowercased == student.first_name.to_lowercase()
|| lowercased == student.last_name.to_lowercase()
|| lowercased == student.full_name_last().to_lowercase()
|| lowercased == student.full_name_first().to_lowercase())
.then_some(student);
if let Some(student) = maybe_student {
matched_student = Some(student);
break;
}
}
matched_student
}
pub fn get_random_student(&self) -> Option<&Student> {
self.students.choose(&mut rand::thread_rng())
}
pub fn get_random_students(&self, amount: usize) -> Vec<&Student> {
self.students
.choose_multiple(&mut rand::thread_rng(), amount)
.collect()
}
pub fn filter(&self) -> StudentFilterOptions {
StudentFilterOptions::new(&self.students)
}
}