Skip to main content

surreal_client/
engine.rs

1use async_trait::async_trait;
2use ciborium::Value as CborValue;
3use serde_json::Value;
4use tokio::sync::mpsc;
5
6use super::error::Result;
7use crate::SurrealError;
8use crate::live::Notification;
9
10/// Wire abstraction for SurrealDB RPC. The CBOR method is the real wire path;
11/// the JSON method is a default convenience that transcodes through it.
12#[async_trait]
13pub trait Engine: Send + Sync {
14    async fn send_message_cbor(&mut self, method: &str, params: CborValue) -> Result<CborValue>;
15
16    async fn send_message(&mut self, method: &str, params: Value) -> Result<Value> {
17        let cbor_params = crate::cbor_convert::json_to_cbor(params);
18        let response = self.send_message_cbor(method, cbor_params).await?;
19        Ok(crate::cbor_convert::cbor_to_json(response))
20    }
21
22    /// Register interest in a live query's notifications.
23    ///
24    /// The caller has already issued the `live` RPC and holds the returned
25    /// query id; this hands back the receiving end of a channel the engine's
26    /// read loop pushes matching [`Notification`]s onto. Only transport engines
27    /// that can receive server-pushed frames (the WebSocket engine) implement
28    /// this — the default refuses, so request/response-only engines (mocks,
29    /// HTTP) surface an honest error.
30    async fn register_live(
31        &mut self,
32        _query_id: &str,
33    ) -> Result<mpsc::UnboundedReceiver<Notification>> {
34        Err(SurrealError::Protocol(
35            "live queries are not supported by this engine".to_string(),
36        ))
37    }
38
39    /// Drop local delivery for a live-query id. Does not send `KILL` — that is
40    /// a separate RPC. Default is a no-op.
41    async fn unregister_live(&mut self, _query_id: &str) {}
42}