summary refs log tree commit diff
path: root/src/main.rs
diff options
context:
space:
mode:
authorSophie Forrest <git@sophieforrest.com>2024-09-05 23:27:11 +1200
committerSophie Forrest <git@sophieforrest.com>2024-09-05 23:27:11 +1200
commit35a0c17ab9e66dfe305b89f6fd72d376d28239e2 (patch)
treea83890471e051705b0d69b71a1abc7a523c7fbff /src/main.rs
parent825b739e917253491183b63ad2f6ce9d8c7181e0 (diff)
feat: use borrows where possible
Avoids excessive cloning.
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs42
1 files changed, 21 insertions, 21 deletions
diff --git a/src/main.rs b/src/main.rs
index 908fdd5..deb15fc 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -10,16 +10,16 @@ use scraper::{CaseSensitivity, Html, Selector};
 
 // TODO: Use string slices to avoid clones?
 #[derive(Clone, Debug, Deserialize, Serialize)]
-struct Course {
-    description: Option<String>,
+struct Course<'a> {
+    description: Option<&'a str>,
     offered: bool,
     points: u8,
     prerequisites: Vec<String>,
     restrictions: Vec<String>,
     subject_areas: HashSet<String>,
-    subtitle: String,
+    subtitle: &'a str,
     timetable: Vec<CourseOffering>,
-    title: String,
+    title: &'a str,
 }
 
 #[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
@@ -61,11 +61,12 @@ impl TryFrom<&str> for Trimester {
 }
 
 #[derive(Clone, Deserialize, Serialize)]
-struct JsonExport {
-    courses: HashMap<String, Course>,
+struct JsonExport<'a> {
+    #[serde(borrow)]
+    courses: HashMap<&'a str, Course<'a>>,
 }
 
-impl Default for Course {
+impl Default for Course<'_> {
     fn default() -> Self {
         Self {
             description: Option::default(),
@@ -74,14 +75,14 @@ impl Default for Course {
             prerequisites: Vec::default(),
             restrictions: Vec::default(),
             subject_areas: HashSet::default(),
-            subtitle: String::default(),
+            subtitle: "",
             timetable: Vec::default(),
-            title: String::default(),
+            title: "",
         }
     }
 }
 
-impl fmt::Display for Course {
+impl fmt::Display for Course<'_> {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         write!(
             f,
@@ -101,14 +102,14 @@ impl fmt::Display for Course {
 
 fn main() {
     tracing_subscriber::fmt()
-        .with_max_level(LevelFilter::INFO)
+        .with_max_level(LevelFilter::ERROR)
         .init();
 
     let html = include_str!("../courses.html");
 
     let document = Html::parse_document(html);
 
-    let mut course_map: HashMap<String, Course> = HashMap::new();
+    let mut course_map: HashMap<&str, Course> = HashMap::new();
 
     let mut subject_area = String::new();
     let mut working_course = Course::default();
@@ -118,31 +119,30 @@ fn main() {
 
         if elem_value.has_class("courseid", CaseSensitivity::AsciiCaseInsensitive) {
             course_map
-                .entry(working_course.title.clone())
+                .entry(working_course.title)
                 .and_modify(|c| {
                     c.subject_areas.insert(subject_area.clone());
                 })
-                .or_insert(working_course.clone());
+                .or_insert(working_course);
             working_course = Course::default();
             working_course.subject_areas.insert(subject_area.clone());
 
             elem.children().for_each(|child| {
                 child.children().for_each(|c| {
                     if c.value().is_text() {
-                        let working = c.value().as_text().unwrap().to_string();
+                        let working = &c.value().as_text().unwrap()[..];
 
                         // Skip over space.
-                        working_course.title = working[..working.len() - 1].to_owned();
+                        working_course.title = &working[..working.len() - 1];
                     } else {
-                        working_course.subtitle = c
+                        working_course.subtitle = &c
                             .first_child()
                             .unwrap()
                             .value()
                             .as_text()
                             .unwrap()
                             // Skip over "- ".
-                            .to_string()[4..]
-                            .to_owned();
+                            [4..];
                     }
                 });
             });
@@ -162,7 +162,7 @@ fn main() {
             let description = elem
                 .first_child()
                 .and_then(|el| el.first_child()?.value().as_text())
-                .map(|t| t.to_string().replace('\n', ""));
+                .map(|t| &t[..]);
 
             working_course.description = description;
 
@@ -221,7 +221,7 @@ fn main() {
 
     debug!("{:?}", course_map.get("COMP 102"));
 
-    course_map.remove(&String::new());
+    course_map.remove("");
 
     fs::write(
         "./export.json",