use async_trait::async_trait;
use ciborium::Value as CborValue;
use serde_json::Value;
use crate::{Engine, Result};
pub struct DebugEngine {
inner: Box<dyn Engine>,
}
impl DebugEngine {
pub fn wrap(engine: Box<dyn Engine>) -> Box<dyn Engine> {
Box::new(Self { inner: engine })
}
fn log_request(&self, method: &str, params: &Value) {
let params_str = serde_json::to_string(params).unwrap_or_default();
println!("🔍 Surreal RPC: {} {}", method, params_str);
}
fn log_response(&self, response: &Value) {
let icon = if let Value::Array(results) = response {
if results
.iter()
.any(|r| r.get("status").and_then(|s| s.as_str()) == Some("ERR"))
{
"❌"
} else {
"✅"
}
} else if response.get("error").is_some() {
"❌"
} else {
"✅"
};
let response_str = serde_json::to_string(response).unwrap_or_default();
println!("{} {}", icon, response_str);
}
}
#[async_trait]
impl Engine for DebugEngine {
async fn send_message(&mut self, method: &str, params: Value) -> Result<Value> {
self.log_request(method, ¶ms);
let response = self.inner.send_message(method, params).await?;
self.log_response(&response);
Ok(response)
}
async fn send_message_cbor(&mut self, method: &str, params: CborValue) -> Result<CborValue> {
println!("🔍 Surreal CBOR RPC: {} {:?}", method, params);
let response = self.inner.send_message_cbor(method, params).await?;
println!("✅ CBOR Response: {:?}", response);
Ok(response)
}
fn supports_cbor(&self) -> bool {
self.inner.supports_cbor()
}
}
#[cfg(test)]
mod tests {
use super::*;
struct MockEngine;
#[async_trait]
impl Engine for MockEngine {
async fn send_message(&mut self, _method: &str, _params: Value) -> Result<Value> {
Ok(serde_json::json!({
"status": "OK",
"result": []
}))
}
async fn send_message_cbor(
&mut self,
_method: &str,
_params: CborValue,
) -> Result<CborValue> {
Ok(CborValue::Map(vec![
(
CborValue::Text("status".to_string()),
CborValue::Text("OK".to_string()),
),
(
CborValue::Text("result".to_string()),
CborValue::Array(vec![]),
),
]))
}
}
#[tokio::test]
async fn test_debug_engine_wraps_correctly() {
let mock = Box::new(MockEngine);
let mut debug_engine = DebugEngine::wrap(mock);
let result = debug_engine
.send_message("test", serde_json::json!(["param1"]))
.await;
assert!(result.is_ok());
}
}