use serde::{Deserialize, Serialize};
use serde_repr::{Deserialize_repr, Serialize_repr};
use crate::types::{PartialEmoji, Snowflake, User};
#[derive(Debug, Clone, Deserialize)]
pub struct Poll {
pub question: PollMedia,
pub answers: Vec<PollAnswer>,
pub expiry: Option<String>,
pub allow_multiselect: bool,
pub layout_type: PollLayoutType,
pub results: Option<PollResults>,
}
#[derive(Debug, Clone, Default, Deserialize, Serialize)]
pub struct PollMedia {
#[serde(skip_serializing_if = "Option::is_none")]
pub text: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub emoji: Option<PartialEmoji>,
}
impl PollMedia {
pub fn text(text: impl Into<String>) -> Self {
Self {
text: Some(text.into()),
emoji: None,
}
}
}
#[derive(Debug, Clone, Deserialize)]
pub struct PollAnswer {
pub answer_id: u32,
pub poll_media: PollMedia,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize_repr, Serialize_repr)]
#[repr(u8)]
pub enum PollLayoutType {
Default = 1,
}
#[derive(Debug, Clone, Deserialize)]
pub struct PollResults {
pub is_finalized: bool,
pub answer_counts: Vec<PollAnswerCount>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct PollAnswerCount {
pub id: u32,
pub count: u32,
pub me_voted: bool,
}
#[derive(Debug, Clone, Default, Serialize)]
pub struct PollCreate {
pub question: PollMedia,
pub answers: Vec<PollAnswerCreate>,
#[serde(skip_serializing_if = "Option::is_none")]
pub duration: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub allow_multiselect: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub layout_type: Option<PollLayoutType>,
}
impl PollCreate {
pub fn new<'a>(question: &str, answers: impl IntoIterator<Item = &'a str>) -> Self {
Self {
question: PollMedia::text(question),
answers: answers
.into_iter()
.map(|answer| PollAnswerCreate {
poll_media: PollMedia::text(answer),
})
.collect(),
..Default::default()
}
}
}
#[derive(Debug, Clone, Default, Serialize)]
pub struct PollAnswerCreate {
pub poll_media: PollMedia,
}
#[derive(Debug, Clone, Deserialize)]
pub struct PollAnswerVoters {
pub users: Vec<User>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct Subscription {
pub id: Snowflake,
pub user_id: Snowflake,
pub sku_ids: Vec<Snowflake>,
pub entitlement_ids: Vec<Snowflake>,
pub renewal_sku_ids: Option<Vec<Snowflake>>,
pub current_period_start: String,
pub current_period_end: String,
pub status: u8,
pub canceled_at: Option<String>,
pub country: Option<String>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct SoundboardSound {
pub name: String,
pub sound_id: Snowflake,
pub volume: f64,
pub emoji_id: Option<Snowflake>,
pub emoji_name: Option<String>,
pub guild_id: Option<Snowflake>,
pub available: bool,
pub user: Option<User>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct GuildCommandPermissions {
pub id: Snowflake,
pub application_id: Snowflake,
pub guild_id: Snowflake,
pub permissions: Vec<CommandPermission>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct CommandPermission {
pub id: Snowflake,
#[serde(rename = "type")]
pub kind: u8,
pub permission: bool,
}
#[cfg(test)]
mod tests {
use serde_json::json;
use super::*;
#[test]
fn polls_round_trip() {
let create = PollCreate::new("Lunch?", ["Pizza", "Tacos"]);
assert_eq!(
serde_json::to_value(&create).unwrap(),
json!({
"question": { "text": "Lunch?" },
"answers": [{ "poll_media": { "text": "Pizza" } }, { "poll_media": { "text": "Tacos" } }],
})
);
let poll: Poll = serde_json::from_value(json!({
"question": { "text": "Lunch?" },
"answers": [{ "answer_id": 1, "poll_media": { "text": "Pizza" } }],
"expiry": "2030-01-01T00:00:00+00:00", "allow_multiselect": false, "layout_type": 1,
"results": { "is_finalized": false, "answer_counts": [{ "id": 1, "count": 3, "me_voted": false }] },
}))
.unwrap();
assert_eq!(poll.results.unwrap().answer_counts[0].count, 3);
}
}