1use crate::error::Result;
2use crate::types::{BraidRequest, BraidResponse, Update};
3use async_trait::async_trait;
4use std::future::Future;
5use std::pin::Pin;
6use std::time::Duration;
7
8pub trait BraidRuntime: Send + Sync + 'static {
10 fn spawn(&self, future: Pin<Box<dyn Future<Output = ()> + Send + 'static>>);
12
13 fn sleep(&self, duration: Duration) -> Pin<Box<dyn Future<Output = ()> + Send + 'static>>;
15
16 fn now_ms(&self) -> u64;
18}
19
20#[async_trait]
22pub trait BraidNetwork: Send + Sync + 'static {
23 async fn fetch(&self, url: &str, req: BraidRequest) -> Result<BraidResponse>;
25
26 async fn subscribe(
28 &self,
29 url: &str,
30 req: BraidRequest,
31 ) -> Result<async_channel::Receiver<Result<Update>>>;
32}
33
34#[async_trait]
36pub trait BraidStorage: Send + Sync + 'static {
37 async fn put(&self, key: &str, data: bytes::Bytes, meta: String) -> Result<()>;
39
40 async fn get(&self, key: &str) -> Result<Option<(bytes::Bytes, String)>>;
42
43 async fn delete(&self, key: &str) -> Result<()>;
45
46 async fn list_keys(&self) -> Result<Vec<String>>;
48}
49
50#[cfg(all(feature = "native", not(target_arch = "wasm32")))]
52pub struct NativeRuntime;
53
54#[cfg(all(feature = "native", not(target_arch = "wasm32")))]
55impl BraidRuntime for NativeRuntime {
56 fn spawn(&self, future: Pin<Box<dyn Future<Output = ()> + Send + 'static>>) {
57 tokio::spawn(future);
58 }
59
60 fn sleep(&self, duration: Duration) -> Pin<Box<dyn Future<Output = ()> + Send + 'static>> {
61 Box::pin(tokio::time::sleep(duration))
62 }
63
64 fn now_ms(&self) -> u64 {
65 std::time::SystemTime::now()
66 .duration_since(std::time::UNIX_EPOCH)
67 .unwrap()
68 .as_millis() as u64
69 }
70}
71
72#[cfg(all(feature = "wasm", target_arch = "wasm32"))]
73pub struct WasmRuntime;
74
75#[cfg(all(feature = "wasm", target_arch = "wasm32"))]
76struct SendFuture<F>(F);
77#[cfg(all(feature = "wasm", target_arch = "wasm32"))]
78unsafe impl<F> Send for SendFuture<F> {}
79#[cfg(all(feature = "wasm", target_arch = "wasm32"))]
80impl<F: Future> Future for SendFuture<F> {
81 type Output = F::Output;
82 fn poll(
83 self: Pin<&mut Self>,
84 cx: &mut std::task::Context<'_>,
85 ) -> std::task::Poll<Self::Output> {
86 let inner = unsafe { self.map_unchecked_mut(|s| &mut s.0) };
87 inner.poll(cx)
88 }
89}
90
91#[cfg(all(feature = "wasm", target_arch = "wasm32"))]
92impl BraidRuntime for WasmRuntime {
93 fn spawn(&self, future: Pin<Box<dyn Future<Output = ()> + Send + 'static>>) {
94 wasm_bindgen_futures::spawn_local(future);
95 }
96
97 fn sleep(&self, duration: Duration) -> Pin<Box<dyn Future<Output = ()> + Send + 'static>> {
98 let f = gloo_timers::future::sleep(duration);
99 Box::pin(SendFuture(f))
100 }
101
102 fn now_ms(&self) -> u64 {
103 js_sys::Date::now() as u64
104 }
105}