weblab_assignment_structure/
lib.rs

1pub enum WeblabAttribute {
2    Test,
3    Library,
4    Solution,
5}
6
7pub struct ProgrammingAssignment {
8    pub title: &'static str,
9    pub weight: f32,
10    pub assignment_text: &'static str,
11
12    pub library_visible: bool,
13    pub spectest_stdout_visible: bool,
14    pub test: &'static str,
15    pub solution: &'static str,
16    pub library: Option<&'static str>,
17    pub test_template: &'static str,
18    pub solution_template: &'static str,
19    pub checklist: Option<Checklist>,
20}
21
22pub struct WeblabFolder {
23    pub title: &'static str,
24    pub weight: Option<f32>,
25    pub assignment_text: &'static str,
26    pub assignments: &'static [WeblabAssignment],
27}
28
29#[derive(Debug)]
30pub enum Checklist {
31    PassFail {
32        items: &'static [&'static str],
33    },
34    Normal {
35        items: &'static [ChecklistItem],
36        total_weight: f32,
37        checklist_percentage: f32,
38    }
39}
40
41#[derive(Debug)]
42pub struct ChecklistItem {
43    pub description: &'static str,
44    pub weight: f32,
45}
46
47pub struct OpenQuestion {
48    pub title: &'static str,
49    pub weight: f32,
50
51    pub assignment_text: &'static str,
52
53    pub expected_answer: &'static str,
54    pub checklist: Option<Checklist>,
55}
56
57pub struct InlineQuestionList {
58    pub title: &'static str,
59    pub weight: Option<f32>,
60
61    pub assignment_text: &'static str,
62
63    pub assignments: &'static [WeblabAssignment],
64}
65
66pub struct MCOption {
67    pub text: &'static str,
68    pub is_correct: bool,
69}
70
71#[derive(Copy, Clone)]
72pub enum MCStyle {
73    AllThatApply,
74    NumCorrect(usize),
75}
76
77impl Default for MCStyle {
78    fn default() -> Self {
79        Self::NumCorrect(1)
80    }
81}
82
83pub struct MCQuestion {
84    pub title: &'static str,
85    pub weight: f32,
86    pub assignment_text: &'static str,
87
88    pub options: &'static [MCOption],
89    pub randomize: bool,
90    pub style: MCStyle,
91    pub explanation: &'static str,
92}
93
94pub enum WeblabAssignment {
95    Programming(ProgrammingAssignment),
96    Open(OpenQuestion),
97    MultipleChoice(MCQuestion),
98    Folder(WeblabFolder),
99    InlineQuestionList(InlineQuestionList),
100}
101
102impl WeblabAssignment {
103    pub fn title(&self) -> &str {
104        match self {
105            WeblabAssignment::Programming(ProgrammingAssignment { title, .. }) => title,
106            WeblabAssignment::Open(OpenQuestion { title, .. }) => title,
107            WeblabAssignment::MultipleChoice(MCQuestion { title, .. }) => title,
108            WeblabAssignment::Folder(WeblabFolder { title, .. }) => title,
109            WeblabAssignment::InlineQuestionList(InlineQuestionList { title, .. }) => title,
110        }
111    }
112
113    pub fn weight(&self) -> f32 {
114        match self {
115            WeblabAssignment::Programming(ProgrammingAssignment {weight, ..}) => *weight,
116            WeblabAssignment::Open(OpenQuestion {weight, ..}) => *weight,
117            WeblabAssignment::MultipleChoice(MCQuestion {weight, ..}) => *weight,
118            WeblabAssignment::Folder(WeblabFolder {weight, assignments, ..}) => {
119                weight.unwrap_or_else(|| {
120                    assignments.iter().map(|i| i.weight()).sum()
121                })
122            }
123            WeblabAssignment::InlineQuestionList(InlineQuestionList { weight, assignments , ..}) => {
124                weight.unwrap_or_else(|| {
125                    assignments.iter().map(|i| i.weight()).sum()
126                })
127            }
128        }
129    }
130
131    pub fn assignment_text(&self) -> &str {
132        match self {
133            WeblabAssignment::Programming(ProgrammingAssignment {
134                assignment_text, ..
135            }) => assignment_text,
136            WeblabAssignment::Open(OpenQuestion {
137                assignment_text, ..
138            }) => assignment_text,
139            WeblabAssignment::MultipleChoice(MCQuestion {
140                assignment_text, ..
141            }) => assignment_text,
142            WeblabAssignment::Folder(WeblabFolder {
143                assignment_text, ..
144            }) => assignment_text,
145            WeblabAssignment::InlineQuestionList(InlineQuestionList {
146                assignment_text, ..
147            }) => assignment_text,
148        }
149    }
150}