Skip to main content

datumesh_store/
pg_unstable.rs

1//! Outside semver until 1.0: this module exposes the `postgres` driver's types, and any
2//! release may change it, including a patch release.
3//!
4//! For what [`PgStore::connect_with`] does not cover: a store whose connections come from
5//! any function returning a `postgres::Client` (client certificates, a custom TLS setup,
6//! session settings), and plain clients that connect exactly as the store does (the same
7//! TLS connector and roots). [`postgres`] is the driver this crate is built with, so a
8//! `Client` made with it is the type [`with_connector`] takes. Depend on an exact version
9//! of this crate (`datumesh-store = "=x.y.z"`) if you use this module.
10
11use std::fmt;
12
13use tokio_postgres_rustls::MakeRustlsConnect;
14
15pub use postgres;
16
17use crate::error::Result;
18use crate::pool::{Pool, PoolOptions};
19use crate::PgStore;
20
21/// A store whose pool opens connections with `connect` (any TLS setup, any configuration).
22/// One connection is opened at once, so a failing connector fails here.
23///
24/// Outside semver until 1.0: this function names the `postgres` driver's types, and any
25/// release may change it, including a patch release.
26pub fn with_connector<F>(connect: F, options: PoolOptions) -> Result<PgStore>
27where
28    F: Fn() -> core::result::Result<postgres::Client, postgres::Error> + Send + Sync + 'static,
29{
30    PgStore::from_pool(Pool::new(Box::new(connect), options))
31}
32
33/// Opens `postgres` clients the way [`PgStore::connect_with`] does: the configuration's
34/// `sslmode` decides whether TLS is used, and when it is, the server's certificate and host
35/// name are verified against the Mozilla roots and the roots of the [`PoolOptions`]
36/// (rustls, ring provider). Cheap to clone.
37///
38/// Outside semver until 1.0: this type names the `postgres` driver's types, and any release
39/// may change it, including a patch release.
40#[derive(Clone)]
41pub struct Connector {
42    config: postgres::Config,
43    tls: MakeRustlsConnect,
44}
45
46impl fmt::Debug for Connector {
47    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
48        f.debug_struct("Connector").field("config", &self.config).finish_non_exhaustive()
49    }
50}
51
52impl Connector {
53    /// A connector for `config`, with the TLS roots of `options` (its pool settings are not
54    /// used). Fails with [`Error::Config`](crate::Error::Config) if a root does not parse.
55    pub fn new(config: postgres::Config, options: &PoolOptions) -> Result<Connector> {
56        Ok(Connector { config, tls: crate::tls::connector(options)? })
57    }
58
59    /// Opens a client.
60    pub fn connect(&self) -> core::result::Result<postgres::Client, postgres::Error> {
61        self.config.connect(self.tls.clone())
62    }
63}