use serde::{Deserialize, Serialize};
use serde_with::serde_as;
use super::CQUSession;
use crate::utils::ApiModel;
#[serde_as]
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Course {
#[serde(alias = "courseName")]
#[serde(default)]
pub name: Option<String>,
#[serde_as(deserialize_as = "serde_with::FromInto<CourseCodeField>")]
#[serde(flatten)]
pub code: Option<String>,
#[serde(alias = "classNbr")]
#[serde(default)]
pub course_num: Option<String>,
#[serde_as(deserialize_as = "serde_with::FromInto<DepartmentField>")]
#[serde(flatten)]
pub dept: Option<String>,
#[serde_as(deserialize_as = "Option<serde_with::PickFirst<(_, serde_with::DisplayFromStr)>>")]
#[serde(alias = "courseCredit")]
#[serde(default)]
pub credit: Option<f64>,
#[serde_as(deserialize_as = "serde_with::FromInto<InstructorField>")]
#[serde(flatten)]
pub instructor: Option<String>,
#[serde(default)]
#[serde_as(deserialize_as = "Option<serde_with::PickFirst<(_, serde_with::DisplayFromStr)>>")]
pub session: Option<CQUSession>,
}
impl ApiModel for Course {}
serde_fallback!(
InstructorField,
String,
instructor,
fallback = [
instructorName,
instructorNames,
classTimetableInstrVOList
],
apply = [
#[serde_with::apply(
_ => #[serde_as(deserialize_as = "Option<serde_with::PickFirst<(_, InstructorVec)>>")]
)]
]
);
serde_fallback!(
DepartmentField,
String,
dept,
fallback = [departmentName, courseDepartmentName, courseDeptShortName]
);
serde_fallback!(
CourseCodeField,
String,
code,
fallback = [courseR, courseCode]
);
serde_with::serde_conv!(
InstructorVec,
String,
|name: &String| [name.clone()],
|value: Vec<String>| -> Result<_, std::convert::Infallible> { Ok(value.join(",")) }
);