headless_lms_models/
lib.rs1#![allow(rustdoc::private_intra_doc_links)]
8pub mod certificate_configuration_to_requirements;
9pub mod certificate_configurations;
10pub mod certificate_fonts;
11pub mod chapters;
12pub mod chatbot_configurations;
13pub mod chatbot_conversation_messages;
14pub mod chatbot_conversations;
15pub mod chatbot_page_sync_statuses;
16pub mod code_giveaway_codes;
17pub mod code_giveaways;
18pub mod course_background_question_answers;
19pub mod course_background_questions;
20pub mod course_custom_privacy_policy_checkbox_texts;
21pub mod course_exams;
22pub mod course_instance_enrollments;
23pub mod course_instances;
24pub mod course_language_groups;
25pub mod course_module_completion_registered_to_study_registries;
26pub mod course_module_completions;
27pub mod course_modules;
28pub mod courses;
29pub mod email_deliveries;
30pub mod email_templates;
31pub mod ended_processed_exams;
32pub mod exams;
33pub mod exercise_language_groups;
34pub mod exercise_repositories;
35pub mod exercise_reset_logs;
36pub mod exercise_service_info;
37pub mod exercise_services;
38pub mod exercise_slide_submissions;
39pub mod exercise_slides;
40pub mod exercise_task_gradings;
41pub mod exercise_task_regrading_submissions;
42pub mod exercise_task_submissions;
43pub mod exercise_tasks;
44pub mod exercises;
45pub mod feedback;
46pub mod file_uploads;
47pub mod flagged_answers;
48pub mod generated_certificates;
49pub mod glossary;
50pub mod join_code_uses;
51pub mod library;
52pub mod marketing_consents;
53pub mod material_references;
54pub mod offered_answers_to_peer_review_temporary;
55pub mod open_university_registration_links;
56pub mod organizations;
57pub mod other_domain_to_course_redirections;
58pub mod page_audio_files;
59pub mod page_history;
60pub mod page_language_groups;
61pub mod page_visit_datum;
62pub mod page_visit_datum_daily_visit_hashing_keys;
63pub mod page_visit_datum_summary_by_courses;
64pub mod page_visit_datum_summary_by_courses_countries;
65pub mod page_visit_datum_summary_by_courses_device_types;
66pub mod page_visit_datum_summary_by_pages;
67pub mod pages;
68pub mod partner_block;
69pub mod peer_or_self_review_configs;
70pub mod peer_or_self_review_question_submissions;
71pub mod peer_or_self_review_questions;
72pub mod peer_or_self_review_submissions;
73pub mod peer_review_queue_entries;
74pub mod pending_roles;
75pub mod playground_examples;
76pub mod privacy_link;
77pub mod proposed_block_edits;
78pub mod proposed_page_edits;
79pub mod regradings;
80pub mod rejected_exercise_slide_submissions;
81pub mod repository_exercises;
82pub mod research_forms;
83pub mod roles;
84pub mod student_countries;
85pub mod study_registry_registrars;
86pub mod suspected_cheaters;
87pub mod teacher_grading_decisions;
88pub mod url_redirections;
89pub mod user_course_instance_exercise_service_variables;
90pub mod user_course_settings;
91pub mod user_details;
92pub mod user_exercise_slide_states;
93pub mod user_exercise_states;
94pub mod user_exercise_task_states;
95pub mod user_research_consents;
96pub mod users;
97
98pub mod error;
99
100pub mod prelude;
101#[cfg(test)]
102pub mod test_helper;
103
104use futures::future::BoxFuture;
105use url::Url;
106use uuid::Uuid;
107
108pub use self::error::{ModelError, ModelErrorType, ModelResult};
109use crate::prelude::*;
110
111#[macro_use]
112extern crate tracing;
113
114pub enum PKeyPolicy<T> {
207 Fixed(T),
210 Generate,
213}
214
215impl<T> PKeyPolicy<T> {
216 pub fn fixed(&self) -> Option<&T> {
218 match self {
219 PKeyPolicy::Fixed(t) => Some(t),
220 PKeyPolicy::Generate => None,
221 }
222 }
223
224 pub fn map<U, F>(self, f: F) -> PKeyPolicy<U>
226 where
227 F: FnOnce(T) -> U,
228 {
229 match self {
230 PKeyPolicy::Fixed(x) => PKeyPolicy::Fixed(f(x)),
231 PKeyPolicy::Generate => PKeyPolicy::Generate,
232 }
233 }
234
235 pub fn map_ref<U, F>(&self, f: F) -> PKeyPolicy<U>
239 where
240 F: FnOnce(&T) -> U,
241 {
242 match self {
243 PKeyPolicy::Fixed(x) => PKeyPolicy::Fixed(f(x)),
244 PKeyPolicy::Generate => PKeyPolicy::Generate,
245 }
246 }
247}
248
249impl PKeyPolicy<Uuid> {
250 pub fn into_uuid(self) -> Uuid {
252 match self {
253 PKeyPolicy::Fixed(uuid) => uuid,
254 PKeyPolicy::Generate => Uuid::new_v4(),
255 }
256 }
257}
258
259#[derive(Clone, Copy)]
261pub enum CourseOrExamId {
262 Course(Uuid),
263 Exam(Uuid),
264}
265
266impl CourseOrExamId {
267 pub fn from(course_id: Option<Uuid>, exam_id: Option<Uuid>) -> ModelResult<Self> {
268 match (course_id, exam_id) {
269 (Some(course_id), None) => Ok(Self::Course(course_id)),
270 (None, Some(exam_id)) => Ok(Self::Exam(exam_id)),
271 (Some(_), Some(_)) => Err(ModelError::new(
272 ModelErrorType::Generic,
273 "Database row had both a course id and an exam id".to_string(),
274 None,
275 )),
276 (None, None) => Err(ModelError::new(
277 ModelErrorType::Generic,
278 "Database row did not have a course id or an exam id".to_string(),
279 None,
280 )),
281 }
282 }
283
284 pub fn to_course_and_exam_ids(self) -> (Option<Uuid>, Option<Uuid>) {
285 match self {
286 Self::Course(instance_id) => (Some(instance_id), None),
287 Self::Exam(exam_id) => (None, Some(exam_id)),
288 }
289 }
290 pub fn exam_id(self) -> Option<Uuid> {
291 if let CourseOrExamId::Exam(id) = self {
292 Some(id)
293 } else {
294 None
295 }
296 }
297}
298
299pub trait SpecFetcher:
305 for<'a> Fn(
306 Url,
307 &'a str,
308 Option<&'a serde_json::Value>,
309) -> BoxFuture<'a, ModelResult<serde_json::Value>>
310{
311}
312
313impl<
314 T: for<'a> Fn(
315 Url,
316 &'a str,
317 Option<&'a serde_json::Value>,
318 ) -> BoxFuture<'a, ModelResult<serde_json::Value>>,
319> SpecFetcher for T
320{
321}