1 module telega.telegram.poll;
2 
3 import std.typecons : Nullable;
4 import telega.botapi : BotApi, TelegramMethod, HTTPMethod, ChatId, isTelegramId;
5 import telega.telegram.basic : Message, MessageEntity, User, ReplyMarkup;
6 import asdf : serializedAs;
7 
8 @serializedAs!PollTypeProxy
9 enum PollType : string
10 {
11     Quiz = "quiz",
12     Regular = "regular"
13 }
14 
15 struct PollTypeProxy
16 {
17     PollType t;
18 
19     this(PollType type)
20     {
21         t = type;
22     }
23 
24     PollType opCast(T : PollType)()
25     {
26         return t;
27     }
28 
29     void serialize(S)(ref S serializer)
30     {
31         serializer.putValue(cast(string)t);
32     }
33 }
34 
35 struct PollOption
36 {
37     string text;
38     uint voter_count;
39 }
40 
41 struct PollAnswer
42 {
43     string poll_id;
44     User user;
45     uint[] option_ids;
46 }
47 
48 struct Poll
49 {
50     string id;
51     string question;
52     PollOption[] options;
53     uint total_voter_count;
54     bool is_closed;
55     bool is_anonymous;
56     string type;
57     bool allows_multiple_answers;
58     Nullable!uint correct_option_id;
59     Nullable!string explanation;
60     Nullable!(MessageEntity[]) explanation_entities;
61     Nullable!uint open_period;
62     Nullable!uint close_date;
63 }
64 
65 struct SendPollMethod
66 {
67     mixin TelegramMethod!"/sendPoll";
68 
69     ChatId chat_id;
70     string question;
71     string[] options;
72     Nullable!bool is_anonymous;
73     Nullable!PollType type;
74     Nullable!bool allows_multiple_answers;
75     Nullable!uint correct_option_id;
76     Nullable!string explanation;
77     Nullable!string explanation_parse_mode;
78     Nullable!ushort open_period;
79     Nullable!uint close_date;
80     Nullable!bool is_closed;
81     Nullable!bool disable_notification;
82     Nullable!uint reply_to_message_id;
83     Nullable!ReplyMarkup reply_markup;
84 }
85 
86 struct StopPollMethod
87 {
88     mixin TelegramMethod!"/stopPoll";
89 
90     ChatId chat_id;
91     uint message_id;
92     Nullable!ReplyMarkup reply_markup;
93 }
94 
95 Message sendPoll(BotApi api, ref SendPollMethod m)
96 {
97     return api.callMethod!Message(m);
98 }
99 
100 Message sendPoll(T1)(BotApi api, T1 chatId, string question, string[] options)
101     if (isTelegramId!T1)
102 {
103     SendPollMethod m = {
104         chat_id: chatId,
105         question: question,
106         options: options
107     };
108 
109     return sendPoll(api, m);
110 }
111 
112 Poll stopPoll(BotApi api, ref StopPollMethod m)
113 {
114     return api.callMethod!Poll(m);
115 }
116 
117 Poll stopPoll(T1)(BotApi api, T1 chatId, uint messageId)
118 {
119     StopPollMethod m = {
120         chat_id: chatId,
121         message_id: messageId
122     };
123 
124     return stopPoll(api, m);
125 }
126 
127 unittest
128 {
129     class BotApiMock : BotApi
130     {
131         this(string token)
132         {
133             super(token);
134         }
135 
136         T callMethod(T, M)(M method)
137         {
138             T result;
139 
140             logDiagnostic("[%d] Requesting %s", requestCounter, method.name);
141 
142             return result;
143         }
144     }
145 
146     auto api = new BotApiMock(null);
147 
148     api.sendPoll("chat-id", "question", ["q1", "q2"]);
149     api.stopPoll("chat-id", 123);
150 }