karyon_jsonrpc/client/
builder.rs1use std::sync::Arc;
2
3use karyon_core::async_runtime::Executor;
4use karyon_net::ToEndpoint;
5
6#[cfg(any(feature = "tcp", feature = "tls", feature = "quic"))]
7use karyon_net::Endpoint;
8
9#[cfg(feature = "quic")]
10use karyon_net::quic::ClientQuicConfig;
11#[cfg(feature = "tcp")]
12use karyon_net::tcp::TcpConfig;
13
14use crate::{
15 client::WsCodec,
16 codec::{JsonCodec, JsonRpcCodec},
17 error::Result,
18};
19
20#[cfg(any(feature = "tcp", feature = "tls", feature = "quic"))]
21use crate::error::Error;
22
23use super::{Client, ClientConfig};
24
25const DEFAULT_TIMEOUT: u64 = 3000;
26const DEFAULT_MAX_SUBSCRIPTION_BUFFER_SIZE: usize = 20000;
27
28pub struct ClientBuilder<B, W = JsonCodec> {
49 inner: ClientConfig,
50 byte_codec: B,
51 ws_codec: W,
52 executor: Option<Executor>,
53}
54
55impl ClientBuilder<JsonCodec, JsonCodec> {
56 pub fn new(endpoint: impl ToEndpoint) -> Result<ClientBuilder<JsonCodec, JsonCodec>> {
58 ClientBuilder::new_with_codec(endpoint, JsonCodec::default())
59 }
60}
61
62impl<B: JsonRpcCodec> ClientBuilder<B, JsonCodec> {
63 pub fn new_with_codec(
67 endpoint: impl ToEndpoint,
68 codec: B,
69 ) -> Result<ClientBuilder<B, JsonCodec>> {
70 let endpoint = endpoint.to_endpoint()?;
71 Ok(ClientBuilder {
72 inner: ClientConfig {
73 endpoint,
74 timeout: Some(DEFAULT_TIMEOUT),
75 #[cfg(feature = "tcp")]
76 tcp_config: Default::default(),
77 #[cfg(feature = "tls")]
78 tls_config: None,
79 #[cfg(feature = "quic")]
80 quic_config: None,
81 subscription_buffer_size: DEFAULT_MAX_SUBSCRIPTION_BUFFER_SIZE,
82 },
83 byte_codec: codec,
84 ws_codec: JsonCodec::default(),
85 executor: None,
86 })
87 }
88}
89
90impl<B, W> ClientBuilder<B, W>
91where
92 B: JsonRpcCodec,
93 W: WsCodec,
94{
95 pub fn set_timeout(mut self, timeout: u64) -> Self {
97 self.inner.timeout = Some(timeout);
98 self
99 }
100
101 pub fn set_max_subscription_buffer_size(mut self, size: usize) -> Self {
103 self.inner.subscription_buffer_size = size;
104 self
105 }
106
107 #[cfg(feature = "tcp")]
109 pub fn tcp_config(mut self, config: TcpConfig) -> Result<Self> {
110 match self.inner.endpoint {
111 Endpoint::Tcp(..) | Endpoint::Tls(..) | Endpoint::Ws(..) | Endpoint::Wss(..) => {
112 self.inner.tcp_config = config;
113 Ok(self)
114 }
115 _ => Err(Error::UnsupportedProtocol(self.inner.endpoint.to_string())),
116 }
117 }
118
119 #[cfg(feature = "tls")]
121 pub fn tls_config(mut self, config: karyon_net::tls::ClientTlsConfig) -> Result<Self> {
122 match self.inner.endpoint {
123 Endpoint::Tls(..) | Endpoint::Wss(..) => {
124 self.inner.tls_config = Some(config);
125 Ok(self)
126 }
127 _ => Err(Error::UnsupportedProtocol(format!(
128 "Invalid tls config for endpoint: {}",
129 self.inner.endpoint
130 ))),
131 }
132 }
133
134 #[cfg(feature = "quic")]
136 pub fn quic_config(mut self, config: ClientQuicConfig) -> Result<Self> {
137 match self.inner.endpoint {
138 Endpoint::Quic(..) => {
139 self.inner.quic_config = Some(config);
140 Ok(self)
141 }
142 #[cfg(feature = "http3")]
143 Endpoint::Http(..) => {
144 self.inner.quic_config = Some(config);
145 Ok(self)
146 }
147 _ => Err(Error::UnsupportedProtocol(format!(
148 "Invalid quic config for endpoint: {}",
149 self.inner.endpoint
150 ))),
151 }
152 }
153
154 #[cfg(feature = "ws")]
157 pub fn with_ws_codec<W2: WsCodec>(self, ws_codec: W2) -> ClientBuilder<B, W2> {
158 ClientBuilder {
159 inner: self.inner,
160 byte_codec: self.byte_codec,
161 ws_codec,
162 executor: self.executor,
163 }
164 }
165
166 pub fn with_executor(mut self, ex: Executor) -> Self {
168 self.executor = Some(ex);
169 self
170 }
171
172 pub async fn build(self) -> Result<Arc<Client<B, W>>> {
174 Client::init(self.inner, self.byte_codec, self.ws_codec, self.executor).await
175 }
176}