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