use std::time::SystemTime;
use crate::raw_types::RawWebRegMeeting;
use crate::types::MeetingDay;
#[inline]
pub fn parse_meeting_type_date(w_meeting: &RawWebRegMeeting) -> (&str, MeetingDay) {
let special_meeting = w_meeting.special_meeting.trim();
if !special_meeting.is_empty() && special_meeting != "TBA" {
assert!(!w_meeting.section_start_date.is_empty());
return (
special_meeting,
MeetingDay::OneTime(w_meeting.start_date.to_string()),
);
}
let regular_meeting = w_meeting.meeting_type.trim();
let day_code = w_meeting.day_code.trim();
assert!(day_code.chars().all(|x| x.is_numeric()));
if day_code.is_empty() {
(regular_meeting, MeetingDay::None)
} else {
(
regular_meeting,
MeetingDay::Repeated(parse_day_code(day_code)),
)
}
}
pub fn parse_day_code(day_code_str: &str) -> Vec<String> {
let mut s = vec![];
day_code_str.chars().for_each(|c| {
if !c.is_numeric() {
return;
}
match c {
'0' => s.push("Su".to_string()),
'1' => s.push("M".to_string()),
'2' => s.push("Tu".to_string()),
'3' => s.push("W".to_string()),
'4' => s.push("Th".to_string()),
'5' => s.push("F".to_string()),
'6' => s.push("Sa".to_string()),
_ => {}
};
});
s
}
const DAYS: [&str; 7] = ["M", "Tu", "W", "Th", "F", "Sa", "Su"];
pub fn parse_binary_days(bin_str: &str) -> Vec<String> {
let mut days = vec![];
if bin_str.len() == 7 {
let day_vec = bin_str.chars().collect::<Vec<_>>();
for (idx, day) in DAYS.iter().enumerate() {
if day_vec[idx] == '1' {
days.push(day.to_string());
}
}
}
days
}
const TERM_ARR: [(&str, (i64, i64)); 7] = [
("SP", (5200, 22)), ("S1", (5210, 22)), ("S2", (5220, 22)), ("S3", (5230, 22)), ("SU", (5240, 22)), ("FA", (5250, 22)), ("WI", (5260, 23)), ];
pub fn get_term_seq_id(term: impl AsRef<str>) -> i64 {
let term = term.as_ref();
if term.len() != 4 {
return 0;
}
let term_init = &term[..2];
let (base_seq_id, base_year) = match TERM_ARR.iter().find(|(term, _)| *term == term_init) {
Some((_, data)) => *data,
None => return 0,
};
let quarter_yr = match term[2..].parse::<i64>() {
Ok(o) => o,
Err(_) => return 0,
};
70 * (quarter_yr - base_year) + base_seq_id
}
#[inline(always)]
pub fn get_formatted_course_num(course_code: &str) -> String {
match course_code.chars().filter(|x| x.is_ascii_digit()).count() {
1 => format!(" {}", course_code),
2 => format!(" {}", course_code),
_ => course_code.to_string(),
}
}
#[inline(always)]
pub(crate) fn get_epoch_time() -> u128 {
SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap()
.as_millis()
}
#[inline(always)]
pub(crate) fn get_instructor_names(instructor_name: &str) -> Vec<String> {
instructor_name
.split(':')
.map(|x| {
if x.contains(';') {
x.split_once(';').unwrap().0.trim().to_string()
} else {
x.trim().to_string()
}
})
.collect()
}
#[inline(always)]
pub(crate) fn get_all_instructors<I>(instructors: I) -> Vec<String>
where
I: Iterator<Item = String>,
{
let mut all_inst = instructors.collect::<Vec<_>>();
all_inst.sort();
all_inst.dedup();
all_inst
}
pub fn format_multiple_courses<T: AsRef<str>>(query: &[T]) -> String {
query
.iter()
.map(|x| {
x.as_ref()
.split_whitespace()
.filter(|s| !s.is_empty())
.collect::<Vec<_>>()
})
.filter(|x| !x.is_empty())
.map(|course| {
course
.iter()
.map(|item| {
match item.chars().next() {
Some(c) if c.is_ascii_digit() => get_formatted_course_num(item),
Some(_) => {
if let Some(idx) = item.find(|c: char| c.is_ascii_digit()) {
let subj = &item[..idx];
let csrc = &item[idx..];
format!("{}:{}", subj, get_formatted_course_num(csrc))
} else {
item.to_string()
}
}
_ => "".to_string(),
}
})
.collect::<Vec<_>>()
.join(":")
})
.collect::<Vec<_>>()
.join(";")
.to_uppercase()
}