use serde::{Deserialize, Serialize};
use std::collections::HashMap;
pub struct GraphMessage;
impl GraphMessage {
pub const TOPIC: &'static str = "/v1.0/graph/api/invoke";
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RequestLine {
#[serde(default = "default_method")]
pub method: String,
#[serde(default = "default_uri")]
pub uri: String,
#[serde(flatten)]
pub extensions: HashMap<String, serde_json::Value>,
}
impl Default for RequestLine {
fn default() -> Self {
Self {
method: "GET".to_owned(),
uri: "/".to_owned(),
extensions: HashMap::new(),
}
}
}
fn default_method() -> String {
"GET".to_owned()
}
fn default_uri() -> String {
"/".to_owned()
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct StatusLine {
#[serde(default = "default_status_code")]
pub code: u16,
#[serde(rename = "reasonPhrase", default = "default_reason")]
pub reason_phrase: String,
#[serde(flatten)]
pub extensions: HashMap<String, serde_json::Value>,
}
impl Default for StatusLine {
fn default() -> Self {
Self {
code: 200,
reason_phrase: "OK".to_owned(),
extensions: HashMap::new(),
}
}
}
fn default_status_code() -> u16 {
200
}
fn default_reason() -> String {
"OK".to_owned()
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct GraphRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub body: Option<String>,
#[serde(rename = "requestLine", default)]
pub request_line: RequestLine,
#[serde(default)]
pub headers: HashMap<String, String>,
#[serde(flatten)]
pub extensions: HashMap<String, serde_json::Value>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct GraphResponse {
#[serde(skip_serializing_if = "Option::is_none")]
pub body: Option<String>,
#[serde(default)]
pub headers: HashMap<String, String>,
#[serde(rename = "statusLine", default)]
pub status_line: StatusLine,
#[serde(flatten)]
pub extensions: HashMap<String, serde_json::Value>,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_graph_request_deserialize() {
let json = r#"{
"body": "{\"key\":\"value\"}",
"requestLine": {"method": "POST", "uri": "/api/test"},
"headers": {"Content-Type": "application/json"}
}"#;
let req: GraphRequest = serde_json::from_str(json).unwrap();
assert_eq!(req.request_line.method, "POST");
assert_eq!(req.request_line.uri, "/api/test");
assert_eq!(req.headers.get("Content-Type").unwrap(), "application/json");
}
#[test]
fn test_graph_response_serialize() {
let resp = GraphResponse {
body: Some(r#"{"result":"ok"}"#.to_owned()),
headers: {
let mut h = HashMap::new();
h.insert("Content-Type".to_owned(), "application/json".to_owned());
h
},
status_line: StatusLine::default(),
extensions: HashMap::new(),
};
let json = serde_json::to_value(&resp).unwrap();
assert_eq!(json["statusLine"]["code"], 200);
assert_eq!(json["statusLine"]["reasonPhrase"], "OK");
}
#[test]
fn test_graph_message_topic() {
assert_eq!(GraphMessage::TOPIC, "/v1.0/graph/api/invoke");
}
#[test]
fn test_request_line_defaults() {
let rl = RequestLine::default();
assert_eq!(rl.method, "GET");
assert_eq!(rl.uri, "/");
}
}