canvas_lms_api/resources/
user.rs1use crate::{
2 error::Result,
3 http::Requester,
4 pagination::PageStream,
5 resources::{
6 communication_channel::CommunicationChannel, course::Course, enrollment::Enrollment,
7 },
8};
9use chrono::{DateTime, Utc};
10use serde::{Deserialize, Serialize};
11use std::sync::Arc;
12
13#[derive(Debug, Clone, Deserialize, Serialize)]
15pub struct User {
16 pub id: u64,
17 pub name: Option<String>,
18 pub sortable_name: Option<String>,
19 pub short_name: Option<String>,
20 pub sis_user_id: Option<String>,
21 pub login_id: Option<String>,
22 pub email: Option<String>,
23 pub avatar_url: Option<String>,
24 pub locale: Option<String>,
25 pub last_login: Option<DateTime<Utc>>,
26 pub time_zone: Option<String>,
27 pub bio: Option<String>,
28
29 #[serde(skip)]
30 pub(crate) requester: Option<Arc<Requester>>,
31}
32
33impl User {
34 fn req(&self) -> &Arc<Requester> {
35 self.requester.as_ref().expect("requester not initialized")
36 }
37
38 pub fn get_courses(&self) -> PageStream<Course> {
43 PageStream::new(
44 Arc::clone(self.req()),
45 &format!("users/{}/courses", self.id),
46 vec![],
47 )
48 }
49
50 pub fn get_enrollments(&self) -> PageStream<Enrollment> {
55 PageStream::new(
56 Arc::clone(self.req()),
57 &format!("users/{}/enrollments", self.id),
58 vec![],
59 )
60 }
61
62 pub fn get_communication_channels(&self) -> PageStream<CommunicationChannel> {
67 let user_id = self.id;
68 PageStream::new_with_injector(
69 Arc::clone(self.req()),
70 &format!("users/{user_id}/communication_channels"),
71 vec![],
72 |mut c: CommunicationChannel, req| {
73 c.requester = Some(Arc::clone(&req));
74 c
75 },
76 )
77 }
78
79 pub async fn create_communication_channel(
87 &self,
88 address: &str,
89 channel_type: &str,
90 ) -> Result<CommunicationChannel> {
91 let params = vec![
92 (
93 "communication_channel[address]".to_string(),
94 address.to_string(),
95 ),
96 (
97 "communication_channel[type]".to_string(),
98 channel_type.to_string(),
99 ),
100 ];
101 let mut channel: CommunicationChannel = self
102 .req()
103 .post(
104 &format!("users/{}/communication_channels", self.id),
105 ¶ms,
106 )
107 .await?;
108 channel.requester = self.requester.clone();
109 Ok(channel)
110 }
111}
112
113#[derive(Debug, Clone, Deserialize, Serialize)]
115pub struct CurrentUser {
116 pub id: u64,
117 pub name: Option<String>,
118 pub sortable_name: Option<String>,
119 pub short_name: Option<String>,
120 pub sis_user_id: Option<String>,
121 pub login_id: Option<String>,
122 pub email: Option<String>,
123 pub avatar_url: Option<String>,
124 pub locale: Option<String>,
125 pub last_login: Option<DateTime<Utc>>,
126 pub time_zone: Option<String>,
127 pub bio: Option<String>,
128 pub effective_locale: Option<String>,
129}
130
131#[derive(Debug, Clone, Deserialize, Serialize)]
133pub struct UserDisplay {
134 pub id: u64,
135 pub display_name: Option<String>,
136 pub avatar_image_url: Option<String>,
137 pub html_url: Option<String>,
138}
139
140pub enum UserId {
142 Id(u64),
143 Current,
144}
145
146impl UserId {
147 pub(crate) fn to_path_segment(&self) -> String {
148 match self {
149 UserId::Id(id) => id.to_string(),
150 UserId::Current => "self".to_string(),
151 }
152 }
153}