use crate::{
methods::Method,
request::RequestBuilder,
types::{AllowedUpdate, Integer, Update, WebhookInfo},
};
use failure::Error;
use serde::Serialize;
use std::{collections::HashSet, time::Duration};
#[derive(Clone, Debug, Default, Serialize)]
pub struct GetUpdates {
#[serde(skip_serializing_if = "Option::is_none")]
offset: Option<Integer>,
#[serde(skip_serializing_if = "Option::is_none")]
limit: Option<Integer>,
#[serde(skip_serializing_if = "Option::is_none")]
timeout: Option<Integer>,
#[serde(skip_serializing_if = "Option::is_none")]
allowed_updates: Option<HashSet<AllowedUpdate>>,
}
impl Method for GetUpdates {
type Response = Vec<Update>;
fn into_request(self) -> Result<RequestBuilder, Error> {
RequestBuilder::json("getUpdates", &self)
}
}
impl GetUpdates {
pub fn offset(mut self, offset: Integer) -> Self {
self.offset = Some(offset);
self
}
pub fn limit(mut self, limit: Integer) -> Self {
self.limit = Some(limit);
self
}
pub fn timeout(mut self, timeout: Duration) -> Self {
self.timeout = Some(timeout.as_secs() as i64);
self
}
pub fn allowed_updates(mut self, allowed_updates: HashSet<AllowedUpdate>) -> Self {
self.allowed_updates = Some(allowed_updates);
self
}
pub fn add_allowed_update(mut self, allowed_update: AllowedUpdate) -> Self {
match self.allowed_updates {
Some(ref mut updates) => {
updates.insert(allowed_update);
}
None => {
let mut updates = HashSet::new();
updates.insert(allowed_update);
self.allowed_updates = Some(updates);
}
};
self
}
}
#[derive(Clone, Debug, Serialize)]
pub struct SetWebhook {
url: String,
#[serde(skip_serializing_if = "Option::is_none")]
certificate: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
max_connections: Option<Integer>,
#[serde(skip_serializing_if = "Option::is_none")]
allowed_updates: Option<HashSet<AllowedUpdate>>,
}
impl SetWebhook {
pub fn new<S: Into<String>>(url: S) -> Self {
SetWebhook {
url: url.into(),
certificate: None,
max_connections: None,
allowed_updates: None,
}
}
pub fn certificate<C: Into<String>>(mut self, certificate: C) -> Self {
self.certificate = Some(certificate.into());
self
}
pub fn max_connections(mut self, max_connections: Integer) -> Self {
self.max_connections = Some(max_connections);
self
}
pub fn allowed_updates(mut self, allowed_updates: HashSet<AllowedUpdate>) -> Self {
self.allowed_updates = Some(allowed_updates);
self
}
pub fn add_allowed_update(mut self, allowed_update: AllowedUpdate) -> Self {
match self.allowed_updates {
Some(ref mut updates) => {
updates.insert(allowed_update);
}
None => {
let mut updates = HashSet::new();
updates.insert(allowed_update);
self.allowed_updates = Some(updates);
}
};
self
}
}
impl Method for SetWebhook {
type Response = bool;
fn into_request(self) -> Result<RequestBuilder, Error> {
RequestBuilder::json("setWebhook", &self)
}
}
#[derive(Clone, Copy, Debug)]
pub struct DeleteWebhook;
impl Method for DeleteWebhook {
type Response = bool;
fn into_request(self) -> Result<RequestBuilder, Error> {
RequestBuilder::empty("deleteWebhook")
}
}
#[derive(Clone, Copy, Debug)]
pub struct GetWebhookInfo;
impl Method for GetWebhookInfo {
type Response = WebhookInfo;
fn into_request(self) -> Result<RequestBuilder, Error> {
RequestBuilder::empty("getWebhookInfo")
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::request::{RequestBody, RequestMethod};
use serde_json::Value;
#[test]
fn get_updates() {
let req = GetUpdates::default().into_request().unwrap().build("host", "token");
assert_eq!(req.method, RequestMethod::Post);
assert_eq!(req.url, "host/bottoken/getUpdates");
match req.body {
RequestBody::Json(data) => {
assert_eq!(String::from_utf8(data).unwrap(), String::from(r#"{}"#));
}
data => panic!("Unexpected request data: {:?}", data),
}
let mut updates = HashSet::new();
updates.insert(AllowedUpdate::Message);
updates.insert(AllowedUpdate::Message);
updates.insert(AllowedUpdate::EditedMessage);
updates.insert(AllowedUpdate::ChannelPost);
updates.insert(AllowedUpdate::EditedChannelPost);
updates.insert(AllowedUpdate::ChosenInlineResult);
let req = GetUpdates::default()
.offset(0)
.limit(10)
.timeout(Duration::from_secs(10))
.allowed_updates(updates)
.add_allowed_update(AllowedUpdate::InlineQuery)
.add_allowed_update(AllowedUpdate::CallbackQuery)
.add_allowed_update(AllowedUpdate::PreCheckoutQuery)
.add_allowed_update(AllowedUpdate::ShippingQuery)
.into_request()
.unwrap()
.build("host", "token");
match req.body {
RequestBody::Json(data) => {
let data: Value = serde_json::from_slice(&data).unwrap();;
assert_eq!(data["offset"], 0);
assert_eq!(data["limit"], 10);
assert_eq!(data["timeout"], 10);
let mut updates: Vec<&str> = data["allowed_updates"]
.as_array()
.unwrap()
.iter()
.map(|x| x.as_str().unwrap())
.collect();
updates.sort();
assert_eq!(
updates,
vec![
"callback_query",
"channel_post",
"chosen_inline_result",
"edited_channel_post",
"edited_message",
"inline_query",
"message",
"pre_checkout_query",
"shipping_query",
]
);
}
data => panic!("Unexpected request data: {:?}", data),
}
let method = GetUpdates::default().add_allowed_update(AllowedUpdate::Message);
assert_eq!(method.allowed_updates.unwrap().len(), 1);
}
#[test]
fn set_webhook() {
let req = SetWebhook::new("url").into_request().unwrap().build("host", "token");
assert_eq!(req.method, RequestMethod::Post);
assert_eq!(req.url, "host/bottoken/setWebhook");
match req.body {
RequestBody::Json(data) => {
assert_eq!(String::from_utf8(data).unwrap(), r#"{"url":"url"}"#);
}
data => panic!("Unexpected request data: {:?}", data),
}
let mut updates = HashSet::new();
updates.insert(AllowedUpdate::Message);
updates.insert(AllowedUpdate::Message);
updates.insert(AllowedUpdate::EditedMessage);
updates.insert(AllowedUpdate::ChannelPost);
updates.insert(AllowedUpdate::EditedChannelPost);
updates.insert(AllowedUpdate::ChosenInlineResult);
let req = SetWebhook::new("url")
.certificate("cert")
.max_connections(10)
.allowed_updates(updates)
.add_allowed_update(AllowedUpdate::InlineQuery)
.add_allowed_update(AllowedUpdate::CallbackQuery)
.add_allowed_update(AllowedUpdate::PreCheckoutQuery)
.add_allowed_update(AllowedUpdate::ShippingQuery)
.into_request()
.unwrap()
.build("host", "token");
assert_eq!(req.method, RequestMethod::Post);
assert_eq!(req.url, "host/bottoken/setWebhook");
match req.body {
RequestBody::Json(data) => {
let data: Value = serde_json::from_slice(&data).unwrap();
assert_eq!(data["certificate"], "cert");
assert_eq!(data["max_connections"], 10);
let mut updates: Vec<&str> = data["allowed_updates"]
.as_array()
.unwrap()
.iter()
.map(|x| x.as_str().unwrap())
.collect();
updates.sort();
assert_eq!(
updates,
vec![
"callback_query",
"channel_post",
"chosen_inline_result",
"edited_channel_post",
"edited_message",
"inline_query",
"message",
"pre_checkout_query",
"shipping_query",
]
);
}
data => panic!("Unexpected request data: {:?}", data),
}
let method = SetWebhook::new("url").add_allowed_update(AllowedUpdate::Message);
assert_eq!(method.allowed_updates.unwrap().len(), 1);
}
#[test]
fn delete_webhook() {
let req = DeleteWebhook.into_request().unwrap().build("host", "token");
assert_eq!(req.method, RequestMethod::Get);
assert_eq!(req.url, "host/bottoken/deleteWebhook");
match req.body {
RequestBody::Empty => {}
data => panic!("Unexpected request data: {:?}", data),
}
}
#[test]
fn get_webhook_info() {
let req = GetWebhookInfo.into_request().unwrap().build("host", "token");
assert_eq!(req.method, RequestMethod::Get);
assert_eq!(req.url, "host/bottoken/getWebhookInfo");
match req.body {
RequestBody::Empty => {}
data => panic!("Unexpected request data: {:?}", data),
}
}
}