use serde::{Deserialize, Serialize};
use serde_json::{Map, Value};
use serde_with::{StringWithSeparator, formats::CommaSeparator, serde_as};
use super::{Course, CourseDayTime};
use crate::{
errors::mycqu::MyCQUResult,
mycqu::utils::mycqu_request_handler,
session::Session,
utils::{
ApiModel,
consts::{MYCQU_API_ENROLL_TIMETABLE_URL, MYCQU_API_TIMETABLE_URL},
datetimes::WeekStrHelper,
models::Period,
},
};
#[serde_as]
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
pub struct CourseTimetable {
#[serde(flatten)]
pub course: Course,
#[serde_as(deserialize_as = "Option<serde_with::DisplayFromStr>")]
#[serde(alias = "selectedStuNum")]
#[serde(default)]
pub stu_num: Option<u16>,
#[serde(alias = "position")]
#[serde(default)]
pub classroom: Option<String>,
#[serde_as(deserialize_as = "serde_with::PickFirst<(_, WeekStrHelper)>")]
#[serde(alias = "teachingWeekFormat")]
#[serde(alias = "weeks")]
pub weeks: Vec<Period>,
#[serde(flatten)]
pub day_time: Option<CourseDayTime>,
#[serde_as(deserialize_as = "serde_with::DefaultOnNull")]
#[serde(alias = "wholeWeekOccupy")]
#[serde(default)]
pub whole_week: bool,
#[serde(alias = "roomName")]
#[serde(default)]
pub classroom_name: Option<String>,
#[serde_as(deserialize_as = "StringWithSeparator::<CommaSeparator, String>")]
#[serde(alias = "exprProjectName")]
#[serde(default)]
pub expr_projects: Vec<String>,
}
impl CourseTimetable {
pub async fn fetch_curr(
session: &Session,
student_id: impl AsRef<str>,
cqu_session_id: u16,
) -> MyCQUResult<Vec<Self>> {
let mut res = mycqu_request_handler(session, |client| {
client
.post(MYCQU_API_TIMETABLE_URL)
.query(&[("sessionId", cqu_session_id)])
.json(&vec![student_id.as_ref()])
})
.await?
.json::<Map<String, Value>>()
.await?;
Self::extract_array(&mut res, "classTimetableVOList")
}
pub async fn fetch_enroll(
session: &Session,
student_id: impl AsRef<str>,
) -> MyCQUResult<Vec<Self>> {
let mut res = mycqu_request_handler(session, |client| {
client.get(format!(
"{}/{}",
MYCQU_API_ENROLL_TIMETABLE_URL,
student_id.as_ref()
))
})
.await?
.json::<Map<String, Value>>()
.await?;
Self::extract_array(&mut res, "data")
}
}
impl ApiModel for CourseTimetable {}