1use std::str::FromStr;
4
5use thiserror::Error;
6
7#[derive(Debug, Clone)]
12pub enum Course {
13 Cse115,
14 Raw(String),
15}
16
17#[derive(Debug, Clone)]
22pub enum Semester {
23 Spring2023,
24 Summer2023,
25 Fall2023,
26 Winter2023,
27 Raw(String),
28}
29
30#[derive(Debug, Clone)]
38pub enum Career {
39 Undergraduate,
40 Graduate,
41 Law,
42 DentalMedicine,
43 Medicine,
44 Pharmacy,
45 Raw(String),
46}
47
48impl Course {
49 pub fn career(&self) -> Option<Career> {
54 match self {
55 Course::Cse115 => Some(Career::Undergraduate),
56 Course::Raw(_) => None,
58 }
59 }
60
61 pub(crate) fn id(&self) -> &str {
63 match self {
64 Course::Cse115 => "004544",
65 Course::Raw(id) => id,
66 }
67 }
68}
69
70impl FromStr for Course {
71 type Err = ParseIdError;
72
73 fn from_str(s: &str) -> Result<Self, Self::Err> {
74 match &*normalize(s) {
75 "CSE115" => Ok(Course::Cse115),
76 _ => Err(ParseIdError::InvalidId {
78 id: "Course".to_owned(),
79 given: s.to_owned(),
80 }),
81 }
82 }
83}
84
85impl Semester {
86 pub(crate) fn id(&self) -> &str {
88 match self {
89 Semester::Spring2023 => "2231",
90 Semester::Summer2023 => "",
91 Semester::Fall2023 => "",
92 Semester::Winter2023 => "",
93 Semester::Raw(id) => id,
94 }
95 }
96}
97
98impl FromStr for Semester {
99 type Err = ParseIdError;
100
101 fn from_str(s: &str) -> Result<Self, Self::Err> {
102 match &*normalize(s) {
103 "SPRING2023" => Ok(Semester::Spring2023),
104 "SUMMER2023" => Ok(Semester::Summer2023),
105 "FALL2023" => Ok(Semester::Fall2023),
106 "WINTER2023" => Ok(Semester::Winter2023),
107 _ => Err(ParseIdError::InvalidId {
108 id: "Semester".to_owned(),
109 given: s.to_owned(),
110 }),
111 }
112 }
113}
114
115impl Career {
116 pub(crate) fn id(&self) -> &str {
118 match self {
119 Career::Undergraduate => "UGRD",
120 Career::Graduate => "GRAD",
121 Career::Law => "LAW",
122 Career::DentalMedicine => "SDM",
123 Career::Medicine => "MED",
124 Career::Pharmacy => "PHRM",
125 Career::Raw(career) => career,
126 }
127 }
128}
129
130impl FromStr for Career {
131 type Err = ParseIdError;
132
133 fn from_str(s: &str) -> Result<Self, Self::Err> {
134 match &*normalize(s) {
135 "UNDERGRADUATE" => Ok(Career::Undergraduate),
136 "GRADUATE" => Ok(Career::Graduate),
137 "LAW" => Ok(Career::Law),
138 "DENTALMEDICINE" => Ok(Career::DentalMedicine),
139 "MEDICINE" => Ok(Career::Medicine),
140 "PHARMACY" => Ok(Career::Pharmacy),
141 _ => Err(ParseIdError::InvalidId {
142 id: "Career".to_owned(),
143 given: s.to_owned(),
144 }),
145 }
146 }
147}
148
149fn normalize(s: &str) -> String {
151 s.chars()
152 .filter(|c| !c.is_whitespace())
153 .collect::<String>()
154 .to_uppercase()
155}
156
157#[derive(Debug, Error)]
159pub enum ParseIdError {
160 #[error("`{given}` is an invalid `{id}``")]
164 InvalidId { id: String, given: String },
165}