nu_analytics/core/models/
plan.rs1use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
7pub struct Plan {
8 pub name: String,
10
11 pub courses: Vec<String>,
13
14 pub degree_id: String,
16
17 pub institution: Option<String>,
19}
20
21impl Plan {
22 #[must_use]
28 pub const fn new(name: String, degree_id: String) -> Self {
29 Self {
30 name,
31 courses: Vec::new(),
32 degree_id,
33 institution: None,
34 }
35 }
36
37 pub fn add_course(&mut self, course_key: String) {
42 if !self.courses.contains(&course_key) {
43 self.courses.push(course_key);
44 }
45 }
46
47 pub fn remove_course(&mut self, course_key: &str) -> bool {
55 if let Some(pos) = self.courses.iter().position(|c| c == course_key) {
56 self.courses.remove(pos);
57 true
58 } else {
59 false
60 }
61 }
62
63 pub fn set_institution(&mut self, institution: String) {
65 self.institution = Some(institution);
66 }
67
68 #[must_use]
70 pub const fn course_count(&self) -> usize {
71 self.courses.len()
72 }
73}
74
75#[cfg(test)]
76mod tests {
77 use super::*;
78
79 #[test]
80 fn test_plan_creation() {
81 let plan = Plan::new(
82 "Standard Track".to_string(),
83 "BS Computer Science".to_string(),
84 );
85
86 assert_eq!(plan.name, "Standard Track");
87 assert_eq!(plan.degree_id, "BS Computer Science");
88 assert!(plan.courses.is_empty());
89 assert!(plan.institution.is_none());
90 }
91
92 #[test]
93 fn test_add_course() {
94 let mut plan = Plan::new(
95 "Standard Track".to_string(),
96 "BS Computer Science".to_string(),
97 );
98
99 plan.add_course("CS1800".to_string());
100 plan.add_course("CS2510".to_string());
101
102 assert_eq!(plan.course_count(), 2);
103 assert!(plan.courses.contains(&"CS1800".to_string()));
104 assert!(plan.courses.contains(&"CS2510".to_string()));
105 }
106
107 #[test]
108 fn test_add_duplicate_course() {
109 let mut plan = Plan::new(
110 "Standard Track".to_string(),
111 "BS Computer Science".to_string(),
112 );
113
114 plan.add_course("CS1800".to_string());
115 plan.add_course("CS1800".to_string());
116
117 assert_eq!(plan.course_count(), 1);
118 }
119
120 #[test]
121 fn test_remove_course() {
122 let mut plan = Plan::new(
123 "Standard Track".to_string(),
124 "BS Computer Science".to_string(),
125 );
126
127 plan.add_course("CS1800".to_string());
128 plan.add_course("CS2510".to_string());
129
130 assert!(plan.remove_course("CS1800"));
131 assert_eq!(plan.course_count(), 1);
132 assert!(!plan.courses.contains(&"CS1800".to_string()));
133
134 assert!(!plan.remove_course("CS1800"));
136 }
137
138 #[test]
139 fn test_set_institution() {
140 let mut plan = Plan::new(
141 "Transfer Plan".to_string(),
142 "BS Computer Science".to_string(),
143 );
144
145 plan.set_institution("Community College".to_string());
146 assert_eq!(plan.institution, Some("Community College".to_string()));
147 }
148
149 #[test]
150 fn test_plan_with_multiple_courses() {
151 let mut plan = Plan::new(
152 "Honors Track".to_string(),
153 "BS Computer Science".to_string(),
154 );
155
156 let courses = vec!["CS1800", "CS2510", "CS3500", "MATH1342"];
157 for course in courses {
158 plan.add_course(course.to_string());
159 }
160
161 assert_eq!(plan.course_count(), 4);
162 }
163}