1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#[cfg(feature = "default-exchanges")]
use crate::default_exchanges::{CacheExchange, DedupExchange, FetchExchange};
use crate::{
client::ClientImpl, default_exchanges::TerminatorExchange, Client, Exchange, ExchangeFactory,
HeaderPair, RequestPolicy
};
use parking_lot::Mutex;
use std::{collections::HashMap, sync::Arc};
pub struct ClientBuilder<M: Exchange = TerminatorExchange> {
exchange: M,
url: String,
extra_headers: Option<Arc<dyn Fn() -> Vec<HeaderPair> + Send + Sync>>,
request_policy: RequestPolicy,
#[cfg(target_arch = "wasm32")]
fetch: Option<js_sys::Function>
}
impl ClientBuilder<TerminatorExchange> {
pub fn new<U: Into<String>>(url: U) -> Self {
ClientBuilder {
exchange: TerminatorExchange,
url: url.into(),
extra_headers: None,
request_policy: RequestPolicy::CacheFirst,
#[cfg(target_arch = "wasm32")]
fetch: None
}
}
}
impl<M: Exchange> ClientBuilder<M> {
#[cfg(feature = "default-exchanges")]
pub fn with_default_exchanges(self) -> ClientBuilder<impl Exchange> {
self.with_exchange(FetchExchange)
.with_exchange(CacheExchange)
.with_exchange(DedupExchange)
}
pub fn with_exchange<TResult, F>(self, exchange_factory: F) -> ClientBuilder<TResult>
where
TResult: Exchange + Send + Sync,
F: ExchangeFactory<M, Output = TResult>
{
let exchange = exchange_factory.build(self.exchange);
ClientBuilder {
exchange,
url: self.url,
extra_headers: self.extra_headers,
request_policy: self.request_policy,
#[cfg(target_arch = "wasm32")]
fetch: self.fetch
}
}
pub fn with_extra_headers(
mut self,
header_fn: impl Fn() -> Vec<HeaderPair> + Send + Sync + 'static
) -> Self {
self.extra_headers = Some(Arc::new(header_fn));
self
}
#[cfg(target_arch = "wasm32")]
pub fn with_js_extra_headers(mut self, header_fn: js_sys::Function) -> Self {
self.extra_headers = Some(crate::wasm::convert_header_fn(header_fn));
self
}
#[cfg(target_arch = "wasm32")]
pub fn with_fetch(mut self, fetch: js_sys::Function) -> Self {
self.fetch = Some(fetch);
self
}
pub fn with_request_policy(mut self, request_policy: RequestPolicy) -> Self {
self.request_policy = request_policy;
self
}
pub fn build(self) -> Client<M> {
let client = ClientImpl {
url: self.url,
exchange: self.exchange,
extra_headers: self.extra_headers,
request_policy: self.request_policy,
active_subscriptions: Arc::new(Mutex::new(HashMap::new())),
#[cfg(target_arch = "wasm32")]
fetch: self.fetch
};
Client(Arc::new(client))
}
}