canvas_lms_api/resources/
course.rs1use crate::{
2 error::Result,
3 http::Requester,
4 pagination::PageStream,
5 params::wrap_params,
6 resources::{
7 assignment::Assignment,
8 discussion_topic::DiscussionTopic,
9 enrollment::Enrollment,
10 file::File,
11 group::Group,
12 module::Module,
13 page::Page,
14 params::{
15 assignment_params::CreateAssignmentParams, course_params::UpdateCourseParams,
16 quiz_params::CreateQuizParams,
17 },
18 quiz::Quiz,
19 section::Section,
20 tab::Tab,
21 types::WorkflowState,
22 user::User,
23 },
24};
25use chrono::{DateTime, Utc};
26use serde::{Deserialize, Serialize};
27use std::sync::Arc;
28
29#[derive(Debug, Clone, Deserialize, Serialize)]
30pub struct Course {
31 pub id: u64,
32 pub name: Option<String>,
33 pub course_code: Option<String>,
34 pub workflow_state: Option<WorkflowState>,
35 pub account_id: Option<u64>,
36 pub root_account_id: Option<u64>,
37 pub enrollment_term_id: Option<u64>,
38 pub sis_course_id: Option<String>,
39 pub start_at: Option<DateTime<Utc>>,
40 pub end_at: Option<DateTime<Utc>>,
41 pub grading_standard_id: Option<u64>,
42 pub is_public: Option<bool>,
43 pub license: Option<String>,
44 pub locale: Option<String>,
45 pub time_zone: Option<String>,
46 pub total_students: Option<u64>,
47 pub default_view: Option<String>,
48 pub syllabus_body: Option<String>,
49 pub public_description: Option<String>,
50 pub hide_final_grades: Option<bool>,
51 pub apply_assignment_group_weights: Option<bool>,
52 pub restrict_enrollments_to_course_dates: Option<bool>,
53
54 #[serde(skip)]
55 pub(crate) requester: Option<Arc<Requester>>,
56}
57
58impl Course {
59 fn req(&self) -> &Arc<Requester> {
60 self.requester.as_ref().expect("requester not initialized")
61 }
62
63 pub fn get_assignments(&self) -> PageStream<Assignment> {
68 PageStream::new(
69 Arc::clone(self.req()),
70 &format!("courses/{}/assignments", self.id),
71 vec![],
72 )
73 }
74
75 pub async fn get_assignment(&self, assignment_id: u64) -> Result<Assignment> {
80 self.req()
81 .get(
82 &format!("courses/{}/assignments/{assignment_id}", self.id),
83 &[],
84 )
85 .await
86 }
87
88 pub async fn create_assignment(&self, params: CreateAssignmentParams) -> Result<Assignment> {
93 let form = wrap_params("assignment", ¶ms);
94 self.req()
95 .post(&format!("courses/{}/assignments", self.id), &form)
96 .await
97 }
98
99 pub fn get_sections(&self) -> PageStream<Section> {
104 PageStream::new(
105 Arc::clone(self.req()),
106 &format!("courses/{}/sections", self.id),
107 vec![],
108 )
109 }
110
111 pub async fn get_section(&self, section_id: u64) -> Result<Section> {
116 self.req()
117 .get(&format!("courses/{}/sections/{section_id}", self.id), &[])
118 .await
119 }
120
121 pub fn get_enrollments(&self) -> PageStream<Enrollment> {
126 PageStream::new(
127 Arc::clone(self.req()),
128 &format!("courses/{}/enrollments", self.id),
129 vec![],
130 )
131 }
132
133 pub fn get_users(&self) -> PageStream<User> {
138 PageStream::new(
139 Arc::clone(self.req()),
140 &format!("courses/{}/users", self.id),
141 vec![],
142 )
143 }
144
145 pub async fn update(&self, params: UpdateCourseParams) -> Result<Course> {
150 let form = wrap_params("course", ¶ms);
151 let mut course: Course = self
152 .req()
153 .put(&format!("courses/{}", self.id), &form)
154 .await?;
155 course.requester = self.requester.clone();
156 Ok(course)
157 }
158
159 pub async fn delete(&self) -> Result<Course> {
164 let params = vec![("event".to_string(), "delete".to_string())];
165 let mut course: Course = self
166 .req()
167 .delete(&format!("courses/{}", self.id), ¶ms)
168 .await?;
169 course.requester = self.requester.clone();
170 Ok(course)
171 }
172
173 pub fn get_quizzes(&self) -> PageStream<Quiz> {
178 PageStream::new(
179 Arc::clone(self.req()),
180 &format!("courses/{}/quizzes", self.id),
181 vec![],
182 )
183 }
184
185 pub async fn get_quiz(&self, quiz_id: u64) -> Result<Quiz> {
190 self.req()
191 .get(&format!("courses/{}/quizzes/{quiz_id}", self.id), &[])
192 .await
193 }
194
195 pub async fn create_quiz(&self, params: CreateQuizParams) -> Result<Quiz> {
200 let form = wrap_params("quiz", ¶ms);
201 self.req()
202 .post(&format!("courses/{}/quizzes", self.id), &form)
203 .await
204 }
205
206 pub fn get_modules(&self) -> PageStream<Module> {
211 PageStream::new(
212 Arc::clone(self.req()),
213 &format!("courses/{}/modules", self.id),
214 vec![],
215 )
216 }
217
218 pub async fn get_module(&self, module_id: u64) -> Result<Module> {
223 self.req()
224 .get(&format!("courses/{}/modules/{module_id}", self.id), &[])
225 .await
226 }
227
228 pub fn get_pages(&self) -> PageStream<Page> {
233 PageStream::new(
234 Arc::clone(self.req()),
235 &format!("courses/{}/pages", self.id),
236 vec![],
237 )
238 }
239
240 pub async fn get_page(&self, url_or_id: &str) -> Result<Page> {
245 self.req()
246 .get(&format!("courses/{}/pages/{url_or_id}", self.id), &[])
247 .await
248 }
249
250 pub fn get_discussion_topics(&self) -> PageStream<DiscussionTopic> {
255 PageStream::new(
256 Arc::clone(self.req()),
257 &format!("courses/{}/discussion_topics", self.id),
258 vec![],
259 )
260 }
261
262 pub async fn get_discussion_topic(&self, topic_id: u64) -> Result<DiscussionTopic> {
267 self.req()
268 .get(
269 &format!("courses/{}/discussion_topics/{topic_id}", self.id),
270 &[],
271 )
272 .await
273 }
274
275 pub fn get_files(&self) -> PageStream<File> {
280 PageStream::new(
281 Arc::clone(self.req()),
282 &format!("courses/{}/files", self.id),
283 vec![],
284 )
285 }
286
287 pub fn get_tabs(&self) -> PageStream<Tab> {
292 PageStream::new(
293 Arc::clone(self.req()),
294 &format!("courses/{}/tabs", self.id),
295 vec![],
296 )
297 }
298
299 pub fn get_groups(&self) -> PageStream<Group> {
304 PageStream::new(
305 Arc::clone(self.req()),
306 &format!("courses/{}/groups", self.id),
307 vec![],
308 )
309 }
310
311 pub async fn upload_file(
319 &self,
320 request: crate::upload::UploadRequest,
321 data: Vec<u8>,
322 ) -> crate::error::Result<crate::resources::file::File> {
323 crate::upload::initiate_and_upload(
324 self.req(),
325 &format!("courses/{}/files", self.id),
326 request,
327 data,
328 )
329 .await
330 }
331}