use std::process;
use crate::Result;
use clap::{Parser, Subcommand};
use tansu_sans_io::ErrorCode;
use tracing::debug;
mod broker;
mod cat;
mod generator;
mod perf;
mod proxy;
mod topic;
mod user;
const DEFAULT_BROKER: &str = "tcp://localhost:9092";
fn storage_engines() -> Vec<&'static str> {
vec![
#[cfg(feature = "dynostore")]
"dynostore",
#[cfg(feature = "libsql")]
"libsql",
#[cfg(feature = "postgres")]
"postgres",
#[cfg(feature = "slatedb")]
"slatedb",
#[cfg(feature = "turso")]
"turso",
]
}
fn lakes() -> Vec<&'static str> {
vec![
#[cfg(feature = "delta")]
"delta",
#[cfg(feature = "iceberg")]
"iceberg",
]
}
fn after_help() -> String {
[
format!("Storage engines: {}", storage_engines().join(", ")),
format!("Data lakes: {}", lakes().join(", ")),
]
.join("\n")
}
#[derive(Clone, Debug, Parser)]
#[command(
name = "tansu",
version,
about,
long_about = None,
after_help = after_help(),
args_conflicts_with_subcommands = true
)]
pub struct Cli {
#[command(subcommand)]
command: Option<Command>,
#[clap(flatten)]
broker: broker::Arg,
}
#[derive(Clone, Debug, Subcommand)]
enum Command {
Broker(Box<broker::Arg>),
Cat {
#[command(subcommand)]
command: cat::Command,
},
Generator(Box<generator::Arg>),
Perf(Box<perf::Arg>),
Proxy(Box<proxy::Arg>),
Topic {
#[command(subcommand)]
command: topic::Command,
},
User {
#[command(subcommand)]
command: user::Command,
},
}
impl Cli {
pub async fn main() -> Result<ErrorCode> {
debug!(
pid = process::id(),
storage = ?storage_engines(),
lakes = ?lakes()
);
let cli = Cli::parse();
match cli.command.unwrap_or(Command::Broker(Box::new(cli.broker))) {
Command::Broker(arg) => arg.main().await,
Command::Cat { command } => command.main().await,
Command::Generator(arg) => arg.main().await,
Command::Perf(arg) => arg.main().await,
Command::Proxy(arg) => tansu_proxy::Proxy::main(
arg.listener_url.into_inner(),
arg.advertised_listener_url.into_inner(),
arg.origin_url.into_inner(),
arg.otlp_endpoint_url
.map(|otlp_endpoint_url| otlp_endpoint_url.into_inner()),
)
.await
.map_err(Into::into),
Command::Topic { command } => command.main().await,
Command::User { command } => command.main().await,
}
}
}