use crate::{error::Result, http::Requester, pagination::PageStream, params::wrap_params};
use serde::{Deserialize, Serialize};
use std::sync::Arc;
#[derive(Debug, Default, Clone, Serialize)]
pub struct CreatePollParams {
pub question: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
}
#[derive(Debug, Default, Clone, Serialize)]
pub struct PollChoiceParams {
pub text: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub is_correct: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub position: Option<u32>,
}
#[derive(Debug, Default, Clone, Serialize)]
pub struct PollSessionParams {
pub course_id: u64,
#[serde(skip_serializing_if = "Option::is_none")]
pub course_section_id: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub has_public_results: Option<bool>,
}
#[derive(Debug, Default, Clone, Serialize)]
pub struct PollSubmissionParams {
pub poll_choice_id: u64,
}
#[derive(Debug, Clone, Deserialize, Serialize, canvas_lms_api_derive::CanvasResource)]
pub struct Poll {
pub id: u64,
pub question: Option<String>,
pub description: Option<String>,
pub total_results: Option<serde_json::Value>,
#[serde(skip)]
pub(crate) requester: Option<Arc<Requester>>,
}
impl Poll {
fn inject(&mut self, req: &Arc<Requester>) {
self.requester = Some(Arc::clone(req));
}
pub async fn update(&self, params: CreatePollParams) -> Result<Poll> {
let form = wrap_params("polls[]", ¶ms);
let val: serde_json::Value = self.req().put(&format!("polls/{}", self.id), &form).await?;
let mut poll: Poll = serde_json::from_value(val["polls"][0].clone())?;
poll.inject(self.req());
Ok(poll)
}
pub async fn delete(&self) -> Result<()> {
self.req().delete_void(&format!("polls/{}", self.id)).await
}
pub async fn get_choice(&self, choice_id: u64) -> Result<PollChoice> {
let val: serde_json::Value = self
.req()
.get(
&format!("polls/{}/poll_choices/{}", self.id, choice_id),
&[],
)
.await?;
let mut choice: PollChoice = serde_json::from_value(val["poll_choices"][0].clone())?;
choice.requester = self.requester.clone();
Ok(choice)
}
pub fn get_choices(&self) -> PageStream<PollChoice> {
let poll_id = self.id;
PageStream::new_with_injector(
Arc::clone(self.req()),
&format!("polls/{poll_id}/poll_choices"),
vec![],
|mut c: PollChoice, req| {
c.requester = Some(Arc::clone(&req));
c
},
)
}
pub async fn create_choice(&self, params: PollChoiceParams) -> Result<PollChoice> {
let form = wrap_params("poll_choice[]", ¶ms);
let val: serde_json::Value = self
.req()
.post(&format!("polls/{}/poll_choices", self.id), &form)
.await?;
let mut choice: PollChoice = serde_json::from_value(val["poll_choices"][0].clone())?;
choice.requester = self.requester.clone();
Ok(choice)
}
pub async fn get_session(&self, session_id: u64) -> Result<PollSession> {
let val: serde_json::Value = self
.req()
.get(
&format!("polls/{}/poll_sessions/{}", self.id, session_id),
&[],
)
.await?;
let mut session: PollSession = serde_json::from_value(val["poll_sessions"][0].clone())?;
session.requester = self.requester.clone();
Ok(session)
}
pub fn get_sessions(&self) -> PageStream<PollSession> {
let poll_id = self.id;
PageStream::new_with_injector(
Arc::clone(self.req()),
&format!("polls/{poll_id}/poll_sessions"),
vec![],
|mut s: PollSession, req| {
s.requester = Some(Arc::clone(&req));
s
},
)
}
pub async fn create_session(&self, params: PollSessionParams) -> Result<PollSession> {
let form = wrap_params("poll_session[]", ¶ms);
let val: serde_json::Value = self
.req()
.post(&format!("polls/{}/poll_sessions", self.id), &form)
.await?;
let mut session: PollSession = serde_json::from_value(val["poll_sessions"][0].clone())?;
session.requester = self.requester.clone();
Ok(session)
}
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct PollChoice {
pub id: u64,
pub poll_id: Option<u64>,
pub text: Option<String>,
pub is_correct: Option<bool>,
pub position: Option<u32>,
#[serde(skip)]
pub(crate) requester: Option<Arc<Requester>>,
}
impl PollChoice {
pub async fn update(&self, params: PollChoiceParams) -> Result<PollChoice> {
let poll_id = self.poll_id.unwrap_or_default();
let form = wrap_params("poll_choice[]", ¶ms);
let val: serde_json::Value = self
.req()
.put(&format!("polls/{poll_id}/poll_choices/{}", self.id), &form)
.await?;
let mut choice: PollChoice = serde_json::from_value(val["poll_choices"][0].clone())?;
choice.requester = self.requester.clone();
Ok(choice)
}
pub async fn delete(&self) -> Result<()> {
let poll_id = self.poll_id.unwrap_or_default();
self.req()
.delete_void(&format!("polls/{poll_id}/poll_choices/{}", self.id))
.await
}
fn req(&self) -> &Arc<Requester> {
self.requester.as_ref().expect("requester not initialized")
}
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct PollSession {
pub id: u64,
pub poll_id: Option<u64>,
pub course_id: Option<u64>,
pub course_section_id: Option<u64>,
pub is_published: Option<bool>,
pub has_public_results: Option<bool>,
pub results: Option<serde_json::Value>,
#[serde(skip)]
pub(crate) requester: Option<Arc<Requester>>,
}
impl PollSession {
fn req(&self) -> &Arc<Requester> {
self.requester.as_ref().expect("requester not initialized")
}
fn poll_id(&self) -> u64 {
self.poll_id.unwrap_or_default()
}
fn endpoint(&self) -> String {
format!("polls/{}/poll_sessions/{}", self.poll_id(), self.id)
}
pub async fn update(&self, params: PollSessionParams) -> Result<PollSession> {
let form = wrap_params("poll_session[]", ¶ms);
let val: serde_json::Value = self.req().put(&self.endpoint(), &form).await?;
let mut session: PollSession = serde_json::from_value(val["poll_sessions"][0].clone())?;
session.requester = self.requester.clone();
Ok(session)
}
pub async fn delete(&self) -> Result<()> {
self.req().delete_void(&self.endpoint()).await
}
pub async fn open(&self) -> Result<PollSession> {
let val: serde_json::Value = self
.req()
.get(&format!("{}/open", self.endpoint()), &[])
.await?;
let mut session: PollSession = serde_json::from_value(val["poll_sessions"][0].clone())?;
session.requester = self.requester.clone();
Ok(session)
}
pub async fn close(&self) -> Result<PollSession> {
let val: serde_json::Value = self
.req()
.get(&format!("{}/close", self.endpoint()), &[])
.await?;
let mut session: PollSession = serde_json::from_value(val["poll_sessions"][0].clone())?;
session.requester = self.requester.clone();
Ok(session)
}
pub async fn get_submission(&self, submission_id: u64) -> Result<PollSubmission> {
let val: serde_json::Value = self
.req()
.get(
&format!("{}/poll_submissions/{submission_id}", self.endpoint()),
&[],
)
.await?;
Ok(serde_json::from_value(val["poll_submissions"][0].clone())?)
}
pub async fn create_submission(&self, params: PollSubmissionParams) -> Result<PollSubmission> {
let form = wrap_params("poll_submissions[]", ¶ms);
let val: serde_json::Value = self
.req()
.post(&format!("{}/poll_submissions", self.endpoint()), &form)
.await?;
Ok(serde_json::from_value(val["poll_submissions"][0].clone())?)
}
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct PollSubmission {
pub id: u64,
pub poll_session_id: Option<u64>,
pub poll_choice_id: Option<u64>,
pub user_id: Option<u64>,
pub created_at: Option<chrono::DateTime<chrono::Utc>>,
}