use serde::{Deserialize, Serialize};
use serde_json::Value;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RpcMessage {
pub id: u64,
pub method: String,
pub params: Vec<Value>,
}
impl RpcMessage {
pub fn new(method: impl Into<String>) -> Self {
Self {
id: 0,
method: method.into(),
params: Vec::new(),
}
}
pub fn with_id(mut self, id: u64) -> Self {
self.id = id;
self
}
pub fn with_params(mut self, params: Vec<Value>) -> Self {
self.params = params;
self
}
pub fn with_param(mut self, param: Value) -> Self {
self.params.push(param);
self
}
pub fn to_json(&self) -> serde_json::Result<String> {
serde_json::to_string(self)
}
pub fn from_json(json: &str) -> serde_json::Result<Self> {
serde_json::from_str(json)
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RpcResponse {
#[serde(skip_serializing_if = "Option::is_none")]
pub id: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub result: Option<Value>,
#[serde(skip_serializing_if = "Option::is_none")]
pub error: Option<RpcError>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RpcError {
pub code: i32,
pub message: String,
}
impl RpcResponse {
pub fn from_json(json: &str) -> serde_json::Result<Self> {
serde_json::from_str(json)
}
pub fn is_error(&self) -> bool {
self.error.is_some()
}
pub fn into_result(self) -> Result<Value, crate::error::SurrealError> {
match self.error {
Some(err) => Err(crate::error::SurrealError::Rpc(err.message)),
None => Ok(self.result.unwrap_or(Value::Null)),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_rpc_message_creation() {
let msg = RpcMessage::new("ping")
.with_id(1)
.with_param(Value::String("test".to_string()));
assert_eq!(msg.id, 1);
assert_eq!(msg.method, "ping");
assert_eq!(msg.params.len(), 1);
}
#[test]
fn test_rpc_message_serialization() {
let msg = RpcMessage::new("query").with_id(42).with_params(vec![
Value::String("SELECT * FROM user".to_string()),
Value::Object(serde_json::Map::new()),
]);
let json = msg.to_json().unwrap();
let deserialized = RpcMessage::from_json(&json).unwrap();
assert_eq!(msg.id, deserialized.id);
assert_eq!(msg.method, deserialized.method);
assert_eq!(msg.params.len(), deserialized.params.len());
}
}