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: lib.rs
    path of file: ./repos/trow/src
    
    the code of the file until where you have to start completion: mod client_interface;

pub mod response;
#[allow(clippy::too_many_arguments)]
mod routes;
pub mod types;

mod registry_interface;
pub mod trow_server;
#[cfg(feature = "sqlite")]
mod users;

use std::net::SocketAddr;
use std::path::Path;
use std::sync::Arc;
use std::{env, fs};

use anyhow::{anyhow, Context, Result};
use axum::extract::FromRef;
use axum_server::tls_rustls::RustlsConfig;
use client_interface::ClientInterface;
use thiserror::Error;
use tracing::{event, Level};
use trow_server::{ImageValidationConfig, RegistryProxiesConfig, TrowServer};
use uuid::Uuid;

//TODO: Make this take a cause or description
#[derive(Error, Debug)]
#[error("invalid data directory")]
pub struct ConfigError {}

#[derive(Clone, Debug)]
pub struct NetAddr {
    pub host: String,
    pub port: u16,
}

#[derive(Debug)]
pub struct TrowServerState {
    pub client: ClientInterface,
    pub config: TrowConfig,
}

impl FromRef<Arc<TrowServerState>> for TrowConfig {
    fn from_ref(state: &Arc<TrowServerState>) -> Self {
        state.config.clone()
    }
}

/*
 * Configuration for Trow. This isn't direct fields on the builder so that we can pass it
 * to Rocket to manage.
 */
#[derive(Clone, Debug)]
pub struct TrowConfig {
    data_dir: String,
    addr: SocketAddr,
    tls: Option<TlsConfig>,
    service_name: String,
    proxy_registry_config: Option<RegistryProxiesConfig>,
    image_validation_config: Option<ImageValidationConfig>,
    dry_run: bool,
    token_secret: String,
    user: Option<UserConfig>,
    cors: Option<Vec<String>>,
}

#[derive(Clone, Debug)]
struct TlsConfig {
    cert_file: String,
    key_file: String,
}

#[derive(Clone, Debug)]
struct UserConfig {
    user: String,
    hash_encoded: String, //Surprised not bytes
}

fn init_trow_server(config: TrowConfig) -> Result<TrowServer> {
    event!(Level::DEBUG, "Starting Trow server");

    //Could pass full config here.
    //Pros: less work, new args added automatically
    //-s: ties frontend to backend, some uneeded/unwanted vars

    let ts = trow_server::build_server(
        &config.data_dir,
        config.proxy_registry_config,
        config.image_validation_config,
    );

    ts.get_server()
}

pub struct TrowBuilder {
    config: TrowConfig,
}

impl TrowBuilder {
    #[allow(clippy::too_many_arguments)]
    pub fn new(
        data_dir: String,
        addr: SocketAddr,
        service_name: String,
        dry_run: bool,
        cors: Option<Vec<String>>,
    ) -> Tr
    
    pub async fn start(&self) -> Result<()> {
        println!(
            "Starting Trow {} on {}",
            env!("CARGO_PKG_VERSION"),
            self.config.addr
        );

        println!(
            "Hostname of this registry (for the MutatingWebhook): {:?}",
            self.config.service_name
        );
        match self.config.image_validation_config {
            Some(ref config) => {
                println!("Image validation webhook configured:");
                println!("  Default action: {}", config.default);
                println!("  Allowed prefixes: {:?}", config.allow);
                println!("  Denied prefixes: {:?}", config.deny);
            }
            None => println!("Image validation webhook not configured"),
        }
        if let Some(proxy_config) = &self.config.proxy_registry_config {
            println!("Proxy registries configured:");
            for config in &proxy_config.registries {
                println!("  - {}: {}", config.alias, config.host);
            }
        } else {
            println!("Proxy registries not configured");
        }

        if self.config.cors.is_some() {
            println!("Cross-Origin Resource Sharing(CORS) requests are allowed\n");
        }

        if self.config.dry_run {
            println!("Dry run, exiting.");
            std::process::exit(0);
        }
        let trow_server = init_trow_server(self.config.clone())?;

        let server_state = TrowServerState {
            config: self.config.clone(),
            client: build_handlers(trow_server)?,
        };

        let app = routes::create_app(server_state);

        // Listen for termination signal
        let handle = axum_server::Handle::new();
        tokio::spawn(shutdown_signal(handle.clone()));

        if let Some(ref tls) = self.config.tls {
            if !(Path::new(&tls.cert_file).is_file() && Path::new(&tls.key_file).is_file()) {
                return Err(anyhow!(
                    "Could not find TLS certificate and key at {} and {}",
                    tls.cert_file,
                    tls.key_file
                ));
            }
            let config = RustlsConfig::from_pem_file(&tls.cert_file, &tls.key_file).await?;
            axum_server::bind_rustls(self.config.addr, config)
                .handle(handle)
                .serve(app.into_make_service())
                .await?;
        } else {
            axum_server::bind(self.config.addr)
                .handle(handle)
                .serve(app.into_make_service())
                .await?;
        };
        Ok(())
    }