Skip to main content

electrum_client_netagnostic/
config.rs

1use std::time::Duration;
2
3/// Configuration for an electrum client
4///
5/// Refer to [`Client::from_config`] and [`ClientType::from_config`].
6///
7/// [`Client::from_config`]: crate::Client::from_config
8/// [`ClientType::from_config`]: crate::ClientType::from_config
9#[derive(Debug, Clone)]
10pub struct Config {
11    /// Proxy socks5 configuration, default None
12    socks5: Option<Socks5Config>,
13    /// timeout in seconds, default None (depends on TcpStream default)
14    timeout: Option<Duration>,
15    /// number of retry if any error, default 1
16    retry: u8,
17    /// when ssl, validate the domain, default true
18    validate_domain: bool,
19    /// maximum WebSocket message/frame size in bytes, default Some(256MB)
20    max_message_size: Option<usize>,
21}
22
23/// Configuration for Socks5
24#[derive(Debug, Clone)]
25pub struct Socks5Config {
26    /// The address of the socks5 service
27    pub addr: String,
28    /// Optional credential for the service
29    pub credentials: Option<Socks5Credential>,
30}
31
32/// Credential for the proxy
33#[derive(Debug, Clone)]
34pub struct Socks5Credential {
35    pub username: String,
36    pub password: String,
37}
38
39/// [Config] Builder
40pub struct ConfigBuilder {
41    config: Config,
42}
43
44impl ConfigBuilder {
45    /// Create a builder with a default config, equivalent to [ConfigBuilder::default()]
46    pub fn new() -> Self {
47        ConfigBuilder {
48            config: Config::default(),
49        }
50    }
51
52    /// Set the socks5 config if Some, it accept an `Option` because it's easier for the caller to use
53    /// in a method chain
54    pub fn socks5(mut self, socks5_config: Option<Socks5Config>) -> Self {
55        self.config.socks5 = socks5_config;
56        self
57    }
58
59    /// Sets the timeout
60    pub fn timeout(mut self, timeout: Option<Duration>) -> Self {
61        self.config.timeout = timeout;
62        self
63    }
64
65    /// Sets the retry attempts number
66    pub fn retry(mut self, retry: u8) -> Self {
67        self.config.retry = retry;
68        self
69    }
70
71    /// Sets if the domain has to be validated
72    pub fn validate_domain(mut self, validate_domain: bool) -> Self {
73        self.config.validate_domain = validate_domain;
74        self
75    }
76
77    /// Sets the maximum WebSocket message/frame size
78    pub fn max_message_size(mut self, v: Option<usize>) -> Self {
79        self.config.max_message_size = v;
80        self
81    }
82
83    /// Return the config and consume the builder
84    pub fn build(self) -> Config {
85        self.config
86    }
87}
88
89impl Default for ConfigBuilder {
90    fn default() -> Self {
91        Self::new()
92    }
93}
94
95impl Socks5Config {
96    /// Socks5Config constructor without credentials
97    pub fn new(addr: impl ToString) -> Self {
98        let addr = addr.to_string().replacen("socks5://", "", 1);
99        Socks5Config {
100            addr,
101            credentials: None,
102        }
103    }
104
105    /// Socks5Config constructor if we have credentials
106    pub fn with_credentials(addr: impl ToString, username: String, password: String) -> Self {
107        let mut config = Socks5Config::new(addr);
108        config.credentials = Some(Socks5Credential { username, password });
109        config
110    }
111}
112
113impl Config {
114    /// Get the configuration for `socks5`
115    ///
116    /// Set this with [`ConfigBuilder::socks5`]
117    pub fn socks5(&self) -> &Option<Socks5Config> {
118        &self.socks5
119    }
120
121    /// Get the configuration for `retry`
122    ///
123    /// Set this with [`ConfigBuilder::retry`]
124    pub fn retry(&self) -> u8 {
125        self.retry
126    }
127
128    /// Get the configuration for `timeout`
129    ///
130    /// Set this with [`ConfigBuilder::timeout`]
131    pub fn timeout(&self) -> Option<Duration> {
132        self.timeout
133    }
134
135    /// Get the configuration for `validate_domain`
136    ///
137    /// Set this with [`ConfigBuilder::validate_domain`]
138    pub fn validate_domain(&self) -> bool {
139        self.validate_domain
140    }
141
142    /// Get the configuration for `max_message_size`
143    ///
144    /// Set this with [`ConfigBuilder::max_message_size`]
145    pub fn max_message_size(&self) -> Option<usize> {
146        self.max_message_size
147    }
148
149    /// Convenience method for calling [`ConfigBuilder::new`]
150    pub fn builder() -> ConfigBuilder {
151        ConfigBuilder::new()
152    }
153}
154
155impl Default for Config {
156    fn default() -> Self {
157        Config {
158            socks5: None,
159            timeout: None,
160            retry: 1,
161            validate_domain: true,
162            max_message_size: Some(256 * 1024 * 1024),
163        }
164    }
165}