bonsaidb_client/
builder.rs1use std::collections::HashMap;
2use std::marker::PhantomData;
3use std::sync::Arc;
4use std::time::Duration;
5
6use bonsaidb_core::api;
7use bonsaidb_core::api::ApiName;
8use bonsaidb_core::networking::CURRENT_PROTOCOL_VERSION;
9#[cfg(not(target_arch = "wasm32"))]
10use fabruic::Certificate;
11#[cfg(not(target_arch = "wasm32"))]
12use tokio::runtime::Handle;
13use url::Url;
14
15use crate::client::{AnyApiCallback, ApiCallback};
16#[cfg(not(target_arch = "wasm32"))]
17use crate::BlockingClient;
18use crate::{AsyncClient, Error};
19
20pub struct Async;
21#[cfg(not(target_arch = "wasm32"))]
22pub struct Blocking;
23
24#[must_use]
26pub struct Builder<AsyncMode> {
27 url: Url,
28 protocol_version: &'static str,
29 custom_apis: HashMap<ApiName, Option<Arc<dyn AnyApiCallback>>>,
30 connect_timeout: Option<Duration>,
31 request_timeout: Option<Duration>,
32 #[cfg(not(target_arch = "wasm32"))]
33 certificate: Option<fabruic::Certificate>,
34 #[cfg(not(target_arch = "wasm32"))]
35 tokio: Option<Handle>,
36 mode: PhantomData<AsyncMode>,
37}
38
39impl<AsyncMode> Builder<AsyncMode> {
40 pub(crate) fn new(url: Url) -> Self {
42 Self {
43 url,
44 protocol_version: CURRENT_PROTOCOL_VERSION,
45 custom_apis: HashMap::new(),
46 request_timeout: None,
47 connect_timeout: None,
48 #[cfg(not(target_arch = "wasm32"))]
49 certificate: None,
50 #[cfg(not(target_arch = "wasm32"))]
51 tokio: None,
52 mode: PhantomData,
53 }
54 }
55
56 #[cfg(not(target_arch = "wasm32"))]
60 #[allow(clippy::missing_const_for_fn)]
61 pub fn with_runtime(mut self, handle: Handle) -> Self {
62 self.tokio = Some(handle);
63 self
64 }
65
66 pub fn with_api<Api: api::Api>(mut self) -> Self {
70 self.custom_apis.insert(Api::name(), None);
71 self
72 }
73
74 pub fn with_api_callback<Api: api::Api>(mut self, callback: ApiCallback<Api>) -> Self {
77 self.custom_apis
78 .insert(Api::name(), Some(Arc::new(callback)));
79 self
80 }
81
82 #[cfg(not(target_arch = "wasm32"))]
84 #[allow(clippy::missing_const_for_fn)]
85 pub fn with_certificate(mut self, certificate: Certificate) -> Self {
86 self.certificate = Some(certificate);
87 self
88 }
89
90 #[cfg(feature = "test-util")]
92 #[allow(clippy::missing_const_for_fn)]
93 pub fn with_protocol_version(mut self, version: &'static str) -> Self {
94 self.protocol_version = version;
95 self
96 }
97
98 pub fn with_request_timeout(mut self, timeout: impl Into<Duration>) -> Self {
102 self.request_timeout = Some(timeout.into());
103 self
104 }
105
106 pub fn with_connect_timeout(mut self, timeout: impl Into<Duration>) -> Self {
111 self.connect_timeout = Some(timeout.into());
112 self
113 }
114
115 fn finish_internal(self) -> Result<AsyncClient, Error> {
116 AsyncClient::new_from_parts(
117 self.url,
118 self.protocol_version,
119 self.custom_apis,
120 self.connect_timeout,
121 self.request_timeout,
122 #[cfg(not(target_arch = "wasm32"))]
123 self.certificate,
124 #[cfg(not(target_arch = "wasm32"))]
125 self.tokio.or_else(|| Handle::try_current().ok()),
126 )
127 }
128}
129
130#[cfg(not(target_arch = "wasm32"))]
131impl Builder<Blocking> {
132 pub fn build(self) -> Result<BlockingClient, Error> {
134 self.finish_internal().map(BlockingClient)
135 }
136}
137
138impl Builder<Async> {
139 pub fn build(self) -> Result<AsyncClient, Error> {
141 self.finish_internal()
142 }
143}