tokio_postgres_rustls_improved/
dynamic_config.rs

1use std::{convert::TryFrom, sync::Arc};
2
3use rustls::pki_types::ServerName;
4use rustls_config_stream::ClientConfigProvider;
5use tokio::io::{AsyncRead, AsyncWrite};
6use tokio_postgres::tls::MakeTlsConnect;
7
8use crate::private;
9
10/// [`MakeTlsConnect`] implementation backed by [`rustls`] with a dynamic TLS client config stream
11/// provided by a [`rustls_config_stream::ClientConfigProvider`].
12#[derive(Clone)]
13pub struct MakeDynamicRustlsConnect {
14    config_provider: Arc<ClientConfigProvider>,
15}
16
17impl MakeDynamicRustlsConnect {
18    /// Creates a new [`MakeDynamicRustlsConnect`] from the provided
19    /// [`Arc<ClientConfigProvider>`].
20    #[must_use]
21    pub const fn new(config_provider: Arc<ClientConfigProvider>) -> Self {
22        Self { config_provider }
23    }
24}
25
26impl<S> MakeTlsConnect<S> for MakeDynamicRustlsConnect
27where
28    S: AsyncRead + AsyncWrite + Unpin + Send + 'static,
29{
30    type Stream = private::RustlsStream<S>;
31    type TlsConnect = private::RustlsConnect;
32    type Error = rustls::pki_types::InvalidDnsNameError;
33
34    /// Creates a new [`MakeDynamicRustlsConnect`] from the given [`ClientConfigProvider`].
35    fn make_tls_connect(&mut self, hostname: &str) -> Result<Self::TlsConnect, Self::Error> {
36        ServerName::try_from(hostname).map(|dns_name| {
37            private::RustlsConnect(private::RustlsConnectData {
38                hostname: dns_name.to_owned(),
39                connector: Arc::clone(&self.config_provider.get_config()).into(),
40            })
41        })
42    }
43}