use std::error::Error;
use std::fmt;
use serde::{Deserialize, Serialize};
use serde_json as json;
#[derive(Debug)]
pub enum MMRSError {
BadJSONData(serde_json::error::Error),
HTTPRequestError(reqwest::Error),
}
impl fmt::Display for MMRSError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
MMRSError::BadJSONData(e) => write!(f, "Error writing to JSON string: {}", e),
MMRSError::HTTPRequestError(e) => write!(f, "Error while sending HTTP POST: {}", e),
}
}
}
impl Error for MMRSError {}
#[derive(Serialize, Deserialize, Default)]
pub struct MMBody {
#[serde(skip_serializing_if = "Option::is_none")]
pub text: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub channel: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub username: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub icon_url: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub icon_emoji: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub attachments: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub r#type: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub props: Option<String>,
}
impl MMBody {
pub fn new() -> MMBody {
MMBody::default()
}
pub fn to_json(self) -> Result<String, MMRSError> {
json::to_string(&self).map_err(MMRSError::BadJSONData)
}
}
#[tokio::main]
pub async fn send_message(uri: &str, body: String) -> Result<reqwest::StatusCode, MMRSError> {
let status_code: reqwest::StatusCode = reqwest::Client::new()
.post(uri)
.body(body)
.send()
.await
.map_err(MMRSError::HTTPRequestError)?
.status();
Ok(status_code)
}
#[cfg(test)]
mod tests {
#[test]
fn create_body() {
use crate as mmrs;
let x: mmrs::MMBody = mmrs::MMBody::new();
assert_eq!(x.text, None);
}
#[test]
fn modify_body() {
use crate as mmrs;
let mut x: mmrs::MMBody = mmrs::MMBody::new();
x.text = Some("Hello world!".to_string());
assert_eq!(x.text, Some("Hello world!".to_string()));
}
#[test]
fn json_check() {
use crate as mmrs;
let x: mmrs::MMBody = mmrs::MMBody {
text: Some("Hello, world!".to_string()),
channel: None,
username: None,
icon_url: None,
icon_emoji: None,
attachments: None,
r#type: None,
props: None,
};
let body = x.to_json().unwrap();
assert_eq!(body, "{\"text\":\"Hello, world!\"}");
}
#[test]
fn send_test() {
use crate as mmrs;
use mockito::{Matcher, Server};
let mut s = Server::new();
let _m = s
.mock("POST", "/")
.match_body(Matcher::JsonString(
"{\"text\":\"Hello, world!\"}".to_string(),
))
.create();
let x: mmrs::MMBody = mmrs::MMBody {
text: Some("Hello, world!".to_string()),
channel: None,
username: None,
icon_url: None,
icon_emoji: None,
attachments: None,
r#type: None,
props: None,
};
let body = x.to_json().unwrap();
assert_eq!(
mmrs::send_message(&s.url(), body.to_string()).unwrap(),
reqwest::StatusCode::OK
);
}
}