1use std::sync::{Arc, OnceLock};
17
18use crate::{
19 backend as old_backend, settings::GLOBAL_SETTINGS, ClientSettings, Request, Response, Result,
20 ViaductError,
21};
22
23#[uniffi::export(with_foreign)]
24#[async_trait::async_trait]
25pub trait Backend: Send + Sync + 'static {
26 async fn send_request(&self, request: Request, settings: ClientSettings) -> Result<Response>;
27}
28
29static REGISTERED_BACKEND: OnceLock<Arc<dyn Backend>> = OnceLock::new();
30
31#[uniffi::export]
32pub fn init_backend(backend: Arc<dyn Backend>) {
33 old_backend::set_backend(Box::leak(Box::new(backend.clone())));
34 if REGISTERED_BACKEND.set(backend).is_err() {
35 error_support::report_error!(
36 "viaduct-multiple-init-backend",
37 "init_backend called multiple times"
38 );
39 }
40}
41
42pub fn get_backend() -> Result<&'static Arc<dyn Backend>> {
43 REGISTERED_BACKEND
44 .get()
45 .ok_or(ViaductError::BackendNotInitialized)
46}
47
48impl old_backend::Backend for Arc<dyn Backend> {
49 fn send(&self, request: crate::Request) -> Result<crate::Response, crate::ViaductError> {
50 let settings = GLOBAL_SETTINGS.read();
51 let client_settings = ClientSettings {
52 timeout: match settings.read_timeout {
53 Some(d) => d.as_millis() as u32,
54 None => 0,
55 },
56 redirect_limit: if settings.follow_redirects { 10 } else { 0 },
57 ..ClientSettings::default()
58 };
59 pollster::block_on(self.send_request(request, client_settings))
60 }
61}