From b05cb12f98f58871463779684bb594f457a082d3 Mon Sep 17 00:00:00 2001 From: Waffle Date: Fri, 6 Sep 2019 01:24:46 +0300 Subject: [PATCH] Fix serialization for requests --- src/core/requests/form_builder.rs | 79 ++++++++++++++++++++----------- src/core/requests/send_message.rs | 2 +- 2 files changed, 53 insertions(+), 28 deletions(-) diff --git a/src/core/requests/form_builder.rs b/src/core/requests/form_builder.rs index 5074e52d..8b530025 100644 --- a/src/core/requests/form_builder.rs +++ b/src/core/requests/form_builder.rs @@ -1,5 +1,7 @@ use reqwest::r#async::multipart::Form; 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` /// from scratch. @@ -12,47 +14,26 @@ impl FormBuilder { Self { form: Form::new() } } - /// Add the supplied key-value pair to this `FormBuilder`. Don't forget to - /// implement `serde::Serialize` for `T`! + /// Add the supplied key-value pair to this `FormBuilder`. pub fn add(self, name: &str, value: &T) -> Self - where - T: Serialize, + where T: ToFormValue + ?Sized { Self { form: self.form.text( name.to_owned(), - serde_json::to_string(value) - .expect("serde_json::to_string failed"), - ), + value.to_form_value() + ) } } /// Adds a key-value pair to the supplied `FormBuilder` if `value` is some. /// Don't forget to implement `serde::Serialize` for `T`! pub fn add_if_some(self, name: &str, value: Option<&T>) -> Self - where - T: Serialize, + where T: ToFormValue + ?Sized { match value { None => Self { form: self.form }, - Some(value) => Self { - 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(), - ), + Some(value) => self.add(name, value), } } @@ -60,3 +41,47 @@ impl FormBuilder { 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(), + } + } +} diff --git a/src/core/requests/send_message.rs b/src/core/requests/send_message.rs index c5bff10f..1da9dfc5 100644 --- a/src/core/requests/send_message.rs +++ b/src/core/requests/send_message.rs @@ -25,7 +25,7 @@ impl<'a> Request<'a> for SendMessage<'a> { Box::pin(async move { let params = FormBuilder::new() .add("chat_id", &self.chat_id) - .add_raw("text", &self.text) + .add::("text", &self.text) .add_if_some("parse_mode", self.parse_mode.as_ref()) .add_if_some( "disable_web_page_preview",