Fix serialization for requests

This commit is contained in:
Waffle 2019-09-06 01:24:46 +03:00
parent d08b418d59
commit b05cb12f98
2 changed files with 53 additions and 28 deletions

View file

@ -1,5 +1,7 @@
use reqwest::r#async::multipart::Form; use reqwest::r#async::multipart::Form;
use serde::Serialize; use serde::Serialize;
use crate::core::types::ParseMode;
use crate::core::requests::ChatId;
/// This is a convenient struct that builds `reqwest::r#async::multipart::Form` /// This is a convenient struct that builds `reqwest::r#async::multipart::Form`
/// from scratch. /// from scratch.
@ -12,47 +14,26 @@ impl FormBuilder {
Self { form: Form::new() } Self { form: Form::new() }
} }
/// Add the supplied key-value pair to this `FormBuilder`. Don't forget to /// Add the supplied key-value pair to this `FormBuilder`.
/// implement `serde::Serialize` for `T`!
pub fn add<T>(self, name: &str, value: &T) -> Self pub fn add<T>(self, name: &str, value: &T) -> Self
where where T: ToFormValue + ?Sized
T: Serialize,
{ {
Self { Self {
form: self.form.text( form: self.form.text(
name.to_owned(), name.to_owned(),
serde_json::to_string(value) value.to_form_value()
.expect("serde_json::to_string failed"), )
),
} }
} }
/// Adds a key-value pair to the supplied `FormBuilder` if `value` is some. /// Adds a key-value pair to the supplied `FormBuilder` if `value` is some.
/// Don't forget to implement `serde::Serialize` for `T`! /// Don't forget to implement `serde::Serialize` for `T`!
pub fn add_if_some<T>(self, name: &str, value: Option<&T>) -> Self pub fn add_if_some<T>(self, name: &str, value: Option<&T>) -> Self
where where T: ToFormValue + ?Sized
T: Serialize,
{ {
match value { match value {
None => Self { form: self.form }, None => Self { form: self.form },
Some(value) => Self { Some(value) => self.add(name, value),
form: self.form.text(
name.to_owned(),
serde_json::to_string(value)
.expect("serde_json::to_string failed"),
),
},
}
}
/// Add the supplied key-value pair to this `FormBuilder`.
/// With raw str value, so `serde_json` will not add redundant `""`
pub fn add_raw(self, name: &str, value: &str) -> Self {
Self {
form: self.form.text(
name.to_owned(),
value.to_owned(),
),
} }
} }
@ -60,3 +41,47 @@ impl FormBuilder {
self.form self.form
} }
} }
pub trait ToFormValue {
fn to_form_value(&self) -> String;
}
macro_rules! impl_for_struct {
($($name:ident),*) => {
$(
impl ToFormValue for $name {
fn to_form_value(&self) -> String {
serde_json::to_string(self).expect("serde_json::to_string failed")
}
}
)*
};
}
impl_for_struct!(
bool, i32, i64
);
impl ToFormValue for str {
fn to_form_value(&self) -> String {
self.to_owned()
}
}
impl ToFormValue for ParseMode {
fn to_form_value(&self) -> String {
match self {
ParseMode::HTML => String::from("HTML"),
ParseMode::Markdown => String::from("Markdown"),
}
}
}
impl ToFormValue for ChatId {
fn to_form_value(&self) -> String {
match self {
ChatId::Id(id) => id.to_string(),
ChatId::ChannelUsername(username) => username.clone(),
}
}
}

View file

@ -25,7 +25,7 @@ impl<'a> Request<'a> for SendMessage<'a> {
Box::pin(async move { Box::pin(async move {
let params = FormBuilder::new() let params = FormBuilder::new()
.add("chat_id", &self.chat_id) .add("chat_id", &self.chat_id)
.add_raw("text", &self.text) .add::<str>("text", &self.text)
.add_if_some("parse_mode", self.parse_mode.as_ref()) .add_if_some("parse_mode", self.parse_mode.as_ref())
.add_if_some( .add_if_some(
"disable_web_page_preview", "disable_web_page_preview",