surreal_client/engines/
debug.rs1use async_trait::async_trait;
4use ciborium::Value as CborValue;
5use serde_json::Value;
6
7use crate::{Engine, Result};
8
9pub struct DebugEngine {
11 inner: Box<dyn Engine>,
12}
13
14impl DebugEngine {
15 pub fn wrap(engine: Box<dyn Engine>) -> Box<dyn Engine> {
17 Box::new(Self { inner: engine })
18 }
19
20 fn log_request(&self, method: &str, params: &Value) {
22 let params_str = serde_json::to_string(params).unwrap_or_default();
23 println!("🔍 Surreal RPC: {} {}", method, params_str);
24 }
25
26 fn log_response(&self, response: &Value) {
28 let icon = if let Value::Array(results) = response {
30 if results
31 .iter()
32 .any(|r| r.get("status").and_then(|s| s.as_str()) == Some("ERR"))
33 {
34 "❌"
35 } else {
36 "✅"
37 }
38 } else if response.get("error").is_some() {
39 "❌"
40 } else {
41 "✅"
42 };
43
44 let response_str = serde_json::to_string(response).unwrap_or_default();
45 println!("{} {}", icon, response_str);
46 }
47}
48
49#[async_trait]
50impl Engine for DebugEngine {
51 async fn send_message(&mut self, method: &str, params: Value) -> Result<Value> {
52 self.log_request(method, ¶ms);
53 let response = self.inner.send_message(method, params).await?;
54 self.log_response(&response);
55 Ok(response)
56 }
57
58 async fn send_message_cbor(&mut self, method: &str, params: CborValue) -> Result<CborValue> {
59 println!("🔍 Surreal CBOR RPC: {} {:?}", method, params);
60 let response = self.inner.send_message_cbor(method, params).await?;
61 println!("✅ CBOR Response: {:?}", response);
62 Ok(response)
63 }
64}
65
66#[cfg(test)]
67mod tests {
68 use super::*;
69
70 struct MockEngine;
71
72 #[async_trait]
73 impl Engine for MockEngine {
74 async fn send_message(&mut self, _method: &str, _params: Value) -> Result<Value> {
75 Ok(serde_json::json!({
76 "status": "OK",
77 "result": []
78 }))
79 }
80
81 async fn send_message_cbor(
82 &mut self,
83 _method: &str,
84 _params: CborValue,
85 ) -> Result<CborValue> {
86 Ok(CborValue::Map(vec![
87 (
88 CborValue::Text("status".to_string()),
89 CborValue::Text("OK".to_string()),
90 ),
91 (
92 CborValue::Text("result".to_string()),
93 CborValue::Array(vec![]),
94 ),
95 ]))
96 }
97 }
98
99 #[tokio::test]
100 async fn test_debug_engine_wraps_correctly() {
101 let mock = Box::new(MockEngine);
102 let mut debug_engine = DebugEngine::wrap(mock);
103
104 let result = debug_engine
105 .send_message("test", serde_json::json!(["param1"]))
106 .await;
107
108 assert!(result.is_ok());
109 }
110}