use serde::{Deserialize, Serialize};
pub use aimdb_core::remote::{
ErrorObject, Event, HelloMessage, RecordMetadata, Request, Response, WelcomeMessage,
};
pub const PROTOCOL_VERSION: &str = "1.0";
pub const CLIENT_NAME: &str = "aimdb-cli";
pub trait RequestExt {
#[allow(clippy::new_ret_no_self)]
fn new(id: u64, method: impl Into<String>) -> Request;
fn with_params(id: u64, method: impl Into<String>, params: serde_json::Value) -> Request;
}
impl RequestExt for Request {
fn new(id: u64, method: impl Into<String>) -> Request {
Request {
id,
method: method.into(),
params: None,
}
}
fn with_params(id: u64, method: impl Into<String>, params: serde_json::Value) -> Request {
Request {
id,
method: method.into(),
params: Some(params),
}
}
}
pub trait ResponseExt {
fn into_result(self) -> Result<serde_json::Value, ErrorObject>;
}
impl ResponseExt for Response {
fn into_result(self) -> Result<serde_json::Value, ErrorObject> {
match self {
Response::Success { result, .. } => Ok(result),
Response::Error { error, .. } => Err(error),
}
}
}
pub fn cli_hello() -> HelloMessage {
HelloMessage {
version: PROTOCOL_VERSION.to_string(),
client: CLIENT_NAME.to_string(),
capabilities: None,
auth_token: None,
}
}
#[derive(Debug, Clone, Deserialize)]
pub struct EventMessage {
pub event: Event,
}
pub fn serialize_message<T: Serialize>(msg: &T) -> Result<String, serde_json::Error> {
Ok(format!("{}\n", serde_json::to_string(msg)?))
}
pub fn parse_message<T: for<'de> Deserialize<'de>>(line: &str) -> Result<T, serde_json::Error> {
serde_json::from_str(line.trim())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_request_serialization() {
let req = Request::new(1, "record.list");
let json = serialize_message(&req).unwrap();
assert!(json.contains("\"method\":\"record.list\""));
assert!(json.ends_with('\n'));
}
#[test]
fn test_response_parsing() {
let json = r#"{"id":1,"result":{"status":"ok"}}"#;
let resp: Response = parse_message(json).unwrap();
let result = resp.into_result().unwrap();
assert_eq!(result["status"], "ok");
}
#[test]
fn test_cli_hello() {
let hello = cli_hello();
assert_eq!(hello.version, PROTOCOL_VERSION);
assert_eq!(hello.client, CLIENT_NAME);
assert!(hello.auth_token.is_none());
}
}