iridium-db 0.3.0

A high-performance vector-graph hybrid storage and indexing engine
use std::path::{Path, PathBuf};

use iridium::features::service::{serve, ServiceConfig, ServiceTlsMode};

pub(crate) fn run_service_validate(
    data_root: Option<&Path>,
    listen: Option<String>,
    telemetry_endpoint: Option<String>,
    tls: String,
    admin_token: Option<String>,
    max_requests: usize,
) {
    let config = match build_config(
        data_root,
        listen,
        telemetry_endpoint,
        tls,
        admin_token,
        max_requests,
    ) {
        Ok(config) => config,
        Err(err) => {
            eprintln!("service config invalid: {}", err);
            std::process::exit(1);
        }
    };
    print!("{}", config.validate().to_json_pretty());
}

pub(crate) fn run_service_serve(
    data_root: Option<&Path>,
    listen: Option<String>,
    telemetry_endpoint: Option<String>,
    tls: String,
    admin_token: Option<String>,
    max_requests: usize,
) {
    let config = match build_config(
        data_root,
        listen,
        telemetry_endpoint,
        tls,
        admin_token,
        max_requests,
    ) {
        Ok(config) => config,
        Err(err) => {
            eprintln!("service config invalid: {}", err);
            std::process::exit(1);
        }
    };
    if let Err(err) = serve(&config) {
        eprintln!("service serve failed: {:?}", err);
        std::process::exit(1);
    }
}

fn build_config(
    data_root: Option<&Path>,
    listen: Option<String>,
    telemetry_endpoint: Option<String>,
    tls: String,
    admin_token: Option<String>,
    max_requests: usize,
) -> Result<ServiceConfig, String> {
    let tls_mode = ServiceTlsMode::parse(&tls)
        .ok_or_else(|| "tls must be one of: disabled, operator-optional".to_string())?;
    let data_dir = if let Some(path) = data_root {
        path.to_path_buf()
    } else {
        std::env::current_dir()
            .map_err(|err| err.to_string())?
            .join("data")
    };
    Ok(ServiceConfig {
        listen_address: listen.unwrap_or_else(|| "127.0.0.1:7001".to_string()),
        data_dir: normalize_data_dir(data_dir),
        telemetry_endpoint: telemetry_endpoint.unwrap_or_else(|| "stdout".to_string()),
        tls_mode,
        admin_token,
        max_requests,
    })
}

fn normalize_data_dir(path: PathBuf) -> PathBuf {
    if path.ends_with("data") {
        path
    } else {
        path.join("data")
    }
}