ruma_events/poll/
response.rs
1use std::{ops::Deref, vec};
4
5use ruma_common::OwnedEventId;
6use ruma_macros::EventContent;
7use serde::{Deserialize, Serialize};
8
9use super::{start::PollContentBlock, validate_selections, PollResponseData};
10use crate::relation::Reference;
11
12#[derive(Clone, Debug, Serialize, Deserialize, EventContent)]
22#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
23#[ruma_event(type = "m.poll.response", kind = MessageLike)]
24pub struct PollResponseEventContent {
25 #[serde(rename = "m.selections")]
27 pub selections: SelectionsContentBlock,
28
29 #[cfg(feature = "unstable-msc3955")]
31 #[serde(
32 default,
33 skip_serializing_if = "ruma_common::serde::is_default",
34 rename = "org.matrix.msc1767.automated"
35 )]
36 pub automated: bool,
37
38 #[serde(rename = "m.relates_to")]
40 pub relates_to: Reference,
41}
42
43impl PollResponseEventContent {
44 pub fn new(selections: SelectionsContentBlock, poll_start_id: OwnedEventId) -> Self {
47 Self {
48 selections,
49 #[cfg(feature = "unstable-msc3955")]
50 automated: false,
51 relates_to: Reference::new(poll_start_id),
52 }
53 }
54}
55
56impl OriginalSyncPollResponseEvent {
57 pub fn data(&self) -> PollResponseData<'_> {
59 PollResponseData {
60 sender: &self.sender,
61 origin_server_ts: self.origin_server_ts,
62 selections: &self.content.selections,
63 }
64 }
65}
66
67impl OriginalPollResponseEvent {
68 pub fn data(&self) -> PollResponseData<'_> {
70 PollResponseData {
71 sender: &self.sender,
72 origin_server_ts: self.origin_server_ts,
73 selections: &self.content.selections,
74 }
75 }
76}
77
78#[derive(Clone, Debug, Serialize, Deserialize)]
80#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
81pub struct SelectionsContentBlock(Vec<String>);
82
83impl SelectionsContentBlock {
84 pub fn is_empty(&self) -> bool {
86 self.0.is_empty()
87 }
88
89 pub fn validate<'a>(
94 &'a self,
95 poll: &PollContentBlock,
96 ) -> Option<impl Iterator<Item = &'a str>> {
97 let answer_ids = poll.answers.iter().map(|a| a.id.as_str()).collect();
98 validate_selections(&answer_ids, poll.max_selections, &self.0)
99 }
100}
101
102impl From<Vec<String>> for SelectionsContentBlock {
103 fn from(value: Vec<String>) -> Self {
104 Self(value)
105 }
106}
107
108impl IntoIterator for SelectionsContentBlock {
109 type Item = String;
110 type IntoIter = vec::IntoIter<String>;
111
112 fn into_iter(self) -> Self::IntoIter {
113 self.0.into_iter()
114 }
115}
116
117impl FromIterator<String> for SelectionsContentBlock {
118 fn from_iter<T: IntoIterator<Item = String>>(iter: T) -> Self {
119 Self(Vec::from_iter(iter))
120 }
121}
122
123impl Deref for SelectionsContentBlock {
124 type Target = [String];
125
126 fn deref(&self) -> &Self::Target {
127 &self.0
128 }
129}