1use std::time;
2
3use snafu::{ensure, ResultExt, Snafu};
4
5use crate::client::ClientError;
6use crate::{Client, Parameters};
7
8#[derive(Debug, Snafu)]
9pub enum BuildError {
10 #[snafu(display("missing host"))]
11 MissingHost,
12
13 #[snafu(display("missing username"))]
14 MissingUsername,
15
16 #[snafu(display("missing password"))]
17 MissingPassword,
18
19 #[snafu(display("failed to build: {}", source))]
20 Build { source: ClientError },
21}
22
23pub struct ClientBuilder {
24 host: Option<String>,
25 username: Option<String>,
26 password: Option<String>,
27
28 pool_idle_timeout: time::Duration,
29 request_timeout: time::Duration,
30
31 metadata_detection: bool,
32}
33
34impl ClientBuilder {
35 pub fn with_host<S: Into<String>>(mut self, host: S) -> Self {
36 self.host = Some(host.into());
37 self
38 }
39
40 pub fn with_username<S: Into<String>>(mut self, username: S) -> Self {
41 self.username = Some(username.into());
42 self
43 }
44
45 pub fn with_password<S: Into<String>>(mut self, password: S) -> Self {
46 self.password = Some(password.into());
47 self
48 }
49
50 pub fn with_pool_idle_timeout<T: Into<time::Duration>>(mut self, timeout: T) -> Self {
51 self.pool_idle_timeout = timeout.into();
52 self
53 }
54
55 pub fn with_request_timeout<T: Into<time::Duration>>(mut self, timeout: T) -> Self {
56 self.request_timeout = timeout.into();
57 self
58 }
59
60 pub fn with_metadata_detection(mut self) -> Self {
61 self.metadata_detection = true;
62 self
63 }
64
65 pub async fn build(self) -> Result<Client, BuildError> {
66 ensure!(self.host.is_some(), MissingHostSnafu);
67 ensure!(self.password.is_some(), MissingPasswordSnafu);
68 ensure!(self.username.is_some(), MissingUsernameSnafu);
69
70 let params = Parameters {
71 host: self.host.unwrap(),
72 username: self.username.unwrap(),
73 password: self.password.unwrap(),
74 pool_idle_timeout: self.pool_idle_timeout,
75 request_timeout: self.request_timeout,
76 };
77
78 Client::new_with_params(params).await.context(BuildSnafu)
79 }
80}
81
82impl Default for ClientBuilder {
83 fn default() -> Self {
84 Self {
85 host: None,
86 username: None,
87 password: None,
88 pool_idle_timeout: time::Duration::from_secs(5),
89 request_timeout: time::Duration::from_secs(60),
90 metadata_detection: false,
91 }
92 }
93}