#![expect(
missing_docs,
reason = "bin crate; internal lib shim exists only to support integration tests"
)]
use clap::{Parser, Subcommand, ValueEnum};
#[cfg(feature = "builtin-sqlite")]
mod runtime;
#[cfg(feature = "builtin-sqlite")]
mod codegen;
#[derive(Clone, Copy, ValueEnum)]
pub(crate) enum ParseOutput {
Summary,
Text,
Json,
}
#[derive(Parser)]
#[command(
name = "syntaqlite",
about = "SQL formatting and analysis tools",
version
)]
pub(crate) struct Cli {
#[cfg(feature = "builtin-sqlite")]
#[arg(long = "dialect")]
pub(crate) dialect_path: Option<String>,
#[cfg(feature = "builtin-sqlite")]
#[arg(long, requires = "dialect_path")]
pub(crate) dialect_name: Option<String>,
#[cfg(feature = "builtin-sqlite")]
#[arg(long)]
pub(crate) sqlite_version: Option<String>,
#[cfg(feature = "builtin-sqlite")]
#[arg(long)]
pub(crate) sqlite_cflag: Vec<String>,
#[command(subcommand)]
pub(crate) command: Command,
}
#[derive(Subcommand)]
pub(crate) enum Command {
#[cfg(feature = "builtin-sqlite")]
Parse {
files: Vec<String>,
#[arg(short = 'e', long = "expression", conflicts_with = "files")]
expression: Option<String>,
#[arg(short, long, value_enum, default_value_t = ParseOutput::Summary)]
output: ParseOutput,
},
#[cfg(feature = "builtin-sqlite")]
Fmt {
files: Vec<String>,
#[arg(short = 'e', long = "expression", conflicts_with = "files")]
expression: Option<String>,
#[arg(short = 'w', long, default_value_t = 80)]
line_width: usize,
#[arg(short = 't', long, default_value_t = 2)]
indent_width: usize,
#[arg(short = 'k', long, value_enum, default_value_t = runtime::KeywordCasing::Upper)]
keyword_case: runtime::KeywordCasing,
#[arg(short = 'i', long)]
in_place: bool,
#[arg(long, conflicts_with = "in_place")]
check: bool,
#[arg(long, default_value_t = true, action = clap::ArgAction::Set)]
semicolons: bool,
},
#[cfg(feature = "builtin-sqlite")]
Validate {
files: Vec<String>,
#[arg(short = 'e', long = "expression", conflicts_with = "files")]
expression: Option<String>,
#[arg(long)]
schema: Vec<String>,
#[arg(long = "experimental-lang")]
lang: Option<runtime::HostLanguage>,
},
#[cfg(feature = "builtin-sqlite")]
Lsp,
#[cfg(feature = "builtin-sqlite")]
Dialect(codegen::DialectArgs),
Version,
#[cfg(feature = "builtin-sqlite")]
#[command(flatten)]
DialectTool(codegen::ToolCommand),
}
#[cfg(feature = "builtin-sqlite")]
pub fn run(name: &str, dialect: Option<syntaqlite::any::AnyDialect>) {
let cli =
Cli::try_parse_from(std::iter::once(name.to_string()).chain(std::env::args().skip(1)))
.unwrap_or_else(|e| e.exit());
let result = runtime::dispatch(cli, dialect);
if let Err(e) = result {
eprintln!("error: {e}");
std::process::exit(1);
}
}