1use postgres::{Client, NoTls};
2use postgres_native_tls::MakeTlsConnector;
3use uuid::Uuid;
4
5use crate::errors::CockLockError;
6use crate::lock::{CockLock, CockLockQueries, DEFAULT_TABLE};
7
8pub struct CockLockBuilder {
9 clients: Vec<Client>,
11 client_connection_strings: Vec<String>,
12 tls_connector: Option<MakeTlsConnector>,
13 table_name: String,
14}
15
16impl Default for CockLockBuilder {
17 fn default() -> Self {
18 Self {
19 clients: vec![],
20 client_connection_strings: vec![],
21 tls_connector: None,
22 table_name: DEFAULT_TABLE.to_owned(),
23 }
24 }
25}
26
27impl CockLockBuilder {
32 pub fn new() -> Self {
34 Self::default()
35 }
36
37 pub fn with_connection_strings<T: ToString>(mut self, connection_strings: Vec<T>) -> Self {
39 for connection_string in connection_strings {
40 self.client_connection_strings
41 .push(connection_string.to_string());
42 }
43 self
44 }
45
46 pub fn with_table_name<T: ToString>(mut self, table_name: T) -> Self {
48 self.table_name = table_name.to_string();
49 self
50 }
51
52 pub fn with_clients(mut self, clients: &mut Vec<Client>) -> Self {
56 self.clients.append(clients);
57 self
58 }
59
60 pub fn build(self) -> Result<CockLock, CockLockError> {
62 let mut clients = self.clients;
63 for connection_string in self.client_connection_strings {
64 match &self.tls_connector {
65 Some(connector) => {
66 clients.push(Client::connect(&connection_string, connector.clone())?);
67 }
68 None => {
69 clients.push(Client::connect(&connection_string, NoTls)?);
70 }
71 }
72 }
73
74 if clients.is_empty() {
75 return Err(CockLockError::NoClients);
76 }
77
78 let instance = CockLock::new(CockLock {
79 id: Uuid::new_v4(),
80 clients,
81 table_name: self.table_name,
82 queries: CockLockQueries::default(),
83 })?;
84
85 Ok(instance)
86 }
87}