You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: helper.rs
    path of file: ./repos/dozer/dozer-ingestion/postgres/src/connection
    
    the code of the file until where you have to start completion: use crate::PostgresConnectorError;

use super::client::Client;
use dozer_ingestion_connector::{
    dozer_types::{
        self,
        log::{debug, error},
        models::connection::ConnectionConfig,
    },
    retry_on_network_failure, tokio,
};
use rustls::client::{ServerCertVerified, ServerCertVerifier};
use rustls::{Certificate, Error, ServerName};
use std::sync::Arc;
use std::time::SystemTime;
use tokio_postgres::config::SslMode;
use tokio_postgres::{Connection, NoTls, Socket};

pub fn map_connection_config(
    auth_details: &ConnectionConfig,
) -> Result<tokio_postgres::Config, PostgresConnectorError> {
    if let ConnectionConfig::Postgres(postgres) = auth_details {
        let config_replenished = match postgres.replenish() {
            Ok(conf) => conf,
            Err(e) => return Err(PostgresConnectorError::WrongConnectionConfiguration(e)),
        };
        let mut config = tokio_postgres::Config::new();
        config
            .host(&config_replenished.host)
            .port(config_replenished.port as u
    
pub async fn connect(config: tokio_postgres::Config) -> Result<Client, PostgresConnectorError> {
    let mut roots = rustls::RootCertStore::empty();
    for cert in
        rustls_native_certs::load_native_certs().map_err(PostgresConnectorError::LoadNativeCerts)?
    {
        if let Err(e) = roots.add(&rustls::Certificate(cert.0)) {
            debug!("Failed to add certificate: {}", e);
        }
    }
    let mut rustls_config = rustls::ClientConfig::builder()
        .with_safe_defaults()
        .with_root_certificates(roots)
        .with_no_client_auth();

    match config.get_ssl_mode() {
        SslMode::Disable => {
            // tokio-postgres::Config::SslMode::Disable + NoTLS connection
            let (client, connection) = connect_helper(config, NoTls)
                .await
                .map_err(PostgresConnectorError::ConnectionFailure)?;
            tokio::spawn(async move {
                if let Err(e) = connection.await {
                    error!("Postgres connection error: {}", e);
                }
            });
            Ok(client)
        }
        SslMode::Prefer => {
            // tokio-postgres::Config::SslMode::Prefer + TLS connection with no verification
            rustls_config
                .dangerous()
                .set_certificate_verifier(Arc::new(AcceptAllVerifier {}));
            let (client, connection) = connect_helper(
                config,
                tokio_postgres_rustls::MakeRustlsConnect::new(rustls_config),
            )
            .await
            .map_err(PostgresConnectorError::ConnectionFailure)?;
            tokio::spawn(async move {
                if let Err(e) = connection.await {
                    error!("Postgres connection error: {}", e);
                }
            });
            Ok(client)
        }
        // SslMode::Allow => unimplemented!(),
        SslMode::Require => {
            // tokio-postgres::Config::SslMode::Require + TLS connection with verification
            let (client, connection) = connect_helper(
                config,
                tokio_postgres_rustls::MakeRustlsConnect::new(rustls_config),
            )
            .await
            .map_err(PostgresConnectorError::ConnectionFailure)?;
            tokio::spawn(async move {
                if let Err(e) = connection.await {
                    error!("Postgres connection error: {}", e);
                }
            });
            Ok(client)
        }
        ssl_mode => Err(PostgresConnectorError::InvalidSslError(ssl_mode)),
    }
}