headless_lms_models/library/credit_registration/
config_validation.rs1use std::borrow::Cow;
9
10use crate::course_module_suotar_configurations::{SuotarConfigCheck, SuotarModuleConfigFacts};
11
12const NO_COURSE_CODE: &str = "No uh_course_code, so nothing can be submitted.";
15const COURSE_CODE_NOT_ALLOWED: &str = "Suotar does not accept this uh_course_code:";
16const NO_ECTS: &str = "No ects_credits, so there is nothing to register.";
17
18#[derive(Debug, Clone, PartialEq, Eq)]
20pub enum CourseCodeVerdict {
21 Allowed,
22 NotAllowed {
24 reason: String,
25 },
26}
27
28impl CourseCodeVerdict {
29 pub fn stored(facts: &SuotarModuleConfigFacts) -> Option<Self> {
32 match facts.stored_course_code_allowed? {
33 true => Some(Self::Allowed),
34 false => Some(Self::NotAllowed {
35 reason: facts
36 .stored_course_code_rejection
37 .clone()
38 .unwrap_or_default(),
39 }),
40 }
41 }
42}
43
44pub fn check_module_config(
50 facts: &SuotarModuleConfigFacts,
51 verdict: Option<&CourseCodeVerdict>,
52) -> SuotarConfigCheck {
53 let mut problems: Vec<Cow<'static, str>> = Vec::new();
54
55 let uh_course_code = facts
56 .uh_course_code
57 .as_deref()
58 .map(str::trim)
59 .filter(|code| !code.is_empty());
60 let (course_code_allowed, checked_course_code, course_code_rejection) =
61 match (uh_course_code, verdict) {
62 (None, _) => {
63 problems.push(NO_COURSE_CODE.into());
64 (Some(false), None, None)
65 }
66 (Some(code), Some(CourseCodeVerdict::Allowed)) => {
67 (Some(true), Some(code.to_string()), None)
68 }
69 (Some(code), Some(CourseCodeVerdict::NotAllowed { reason })) => {
70 problems.push(format!("{COURSE_CODE_NOT_ALLOWED} {reason}").into());
71 (Some(false), Some(code.to_string()), Some(reason.clone()))
72 }
73 (Some(_), None) => (None, None, None),
74 };
75 if facts.ects_credits.is_none() {
76 problems.push(NO_ECTS.into());
77 }
78
79 SuotarConfigCheck {
80 course_code_allowed,
81 checked_course_code,
82 course_code_rejection,
83 message: (!problems.is_empty()).then(|| problems.join(" ")),
84 }
85}