1#![allow(dead_code)]
2
3pub mod batch;
4mod error;
5#[cfg(feature = "pg_interval")]
6pub mod pg_interval;
7pub mod pool;
8mod postgres_client;
9pub mod profiler;
10mod protocol;
11#[cfg(test)]
12mod test_helpers;
13#[cfg(feature = "rustls")]
14pub mod tls;
15#[cfg(feature = "tokio")]
16pub mod tokio_connection;
17mod types;
18
19pub use batch::{CollectBatch, FlattenTuple, TupleAppend};
20pub use error::ElefantClientError;
21#[cfg(feature = "pg_interval")]
22pub use pg_interval::Interval;
23pub use pool::{ConnectionFactory, PoolableClient, PostgresPool};
24pub use postgres_client::*;
25pub use protocol::FieldDescription;
26pub use types::*;
27
28#[cfg(feature = "derive")]
29pub use elefant_client_macros::PostgresEnum;
30
31#[derive(Clone)]
32pub struct PostgresConnectionSettings {
33 pub host: String,
34 pub port: u16,
35 pub user: String,
36 pub password: String,
37 pub database: String,
38 pub options: Option<String>,
39 pub replication: Option<String>,
40 enum_type_names: Vec<&'static str>,
41 #[cfg(feature = "rustls")]
42 pub tls: TlsSettings,
43}
44
45impl PostgresConnectionSettings {
46 pub fn new(host: impl Into<String>) -> Self {
47 Self {
48 host: host.into(),
49 ..Self::default()
50 }
51 }
52
53 pub fn port(mut self, port: u16) -> Self {
54 self.port = port;
55 self
56 }
57
58 pub fn user(mut self, user: impl Into<String>) -> Self {
59 self.user = user.into();
60 self
61 }
62
63 pub fn password(mut self, password: impl Into<String>) -> Self {
64 self.password = password.into();
65 self
66 }
67
68 pub fn database(mut self, database: impl Into<String>) -> Self {
69 self.database = database.into();
70 self
71 }
72
73 pub fn options(mut self, options: impl Into<String>) -> Self {
74 self.options = Some(options.into());
75 self
76 }
77
78 pub fn replication(mut self, replication: impl Into<String>) -> Self {
79 self.replication = Some(replication.into());
80 self
81 }
82
83 pub fn register_enum<T: PostgresEnum>(mut self) -> Self {
85 if !self.enum_type_names.contains(&T::PG_TYPE_NAME) {
86 self.enum_type_names.push(T::PG_TYPE_NAME);
87 }
88
89 self
90 }
91
92 pub fn enum_type_names(&self) -> &[&'static str] {
94 &self.enum_type_names
95 }
96
97 #[cfg(feature = "rustls")]
98 pub fn tls(mut self, tls: TlsSettings) -> Self {
99 self.tls = tls;
100 self
101 }
102}
103
104impl Default for PostgresConnectionSettings {
105 fn default() -> Self {
106 Self {
107 host: "localhost".to_string(),
108 port: 5432,
109 user: "postgres".to_string(),
110 password: String::new(),
111 database: "postgres".to_string(),
112 options: None,
113 replication: None,
114 enum_type_names: Vec::new(),
115 #[cfg(feature = "rustls")]
116 tls: TlsSettings::disable(),
117 }
118 }
119}
120
121#[cfg(feature = "rustls")]
122#[derive(Clone)]
123pub enum TlsSettings {
124 Disabled,
126 Prefer(std::sync::Arc<rustls::ClientConfig>),
128 Require(std::sync::Arc<rustls::ClientConfig>),
130}
131
132#[cfg(feature = "rustls")]
133impl std::fmt::Debug for TlsSettings {
134 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
135 match self {
136 Self::Disabled => write!(f, "Disabled"),
137 Self::Prefer(_) => write!(f, "Prefer(...)"),
138 Self::Require(_) => write!(f, "Require(...)"),
139 }
140 }
141}
142
143#[cfg(feature = "rustls")]
144impl TlsSettings {
145 pub fn disable() -> Self {
146 Self::Disabled
147 }
148
149 pub fn prefer(config: std::sync::Arc<rustls::ClientConfig>) -> Self {
150 Self::Prefer(config)
151 }
152
153 pub fn require(config: std::sync::Arc<rustls::ClientConfig>) -> Self {
154 Self::Require(config)
155 }
156
157 pub fn config(&self) -> Option<&std::sync::Arc<rustls::ClientConfig>> {
158 match self {
159 Self::Disabled => None,
160 Self::Prefer(c) | Self::Require(c) => Some(c),
161 }
162 }
163
164 pub fn is_required(&self) -> bool {
165 matches!(self, Self::Require(_))
166 }
167}