pub mod check;
#[cfg(feature = "cli-complete")]
mod completions;
#[cfg(feature = "docker")]
mod docker;
mod languages;
mod ping;
mod words;
use std::io;
use clap::{CommandFactory, Parser, Subcommand};
use enum_dispatch::enum_dispatch;
use is_terminal::IsTerminal;
#[cfg(feature = "annotate")]
use termcolor::{ColorChoice, StandardStream};
#[cfg(feature = "docker")]
pub use docker::Docker;
use crate::{
api::server::{ServerCli, ServerClient},
error::Result,
};
#[derive(Parser, Debug)]
#[command(
author,
version,
about = "LanguageTool API bindings in Rust.",
propagate_version(true),
subcommand_required(true),
verbatim_doc_comment
)]
pub struct Cli {
#[arg(short, long, value_name = "WHEN", default_value = "auto", default_missing_value = "always", num_args(0..=1), require_equals(true))]
pub color: clap::ColorChoice,
#[command(flatten, next_help_heading = "Server options")]
pub server_cli: ServerCli,
#[command(subcommand)]
#[allow(missing_docs)]
pub command: Command,
#[command(flatten)]
#[allow(missing_docs)]
pub verbose: clap_verbosity_flag::Verbosity<clap_verbosity_flag::WarnLevel>,
}
#[derive(Subcommand, Debug)]
#[enum_dispatch]
#[allow(missing_docs)]
pub enum Command {
Check(check::Command),
#[cfg(feature = "docker")]
Docker(docker::Command),
#[clap(visible_alias = "lang")]
Languages(languages::Command),
Ping(ping::Command),
Words(words::Command),
#[cfg(feature = "cli-complete")]
Completions(completions::Command),
}
#[enum_dispatch(Command)]
trait ExecuteSubcommand {
async fn execute(self, stdout: StandardStream, server_client: ServerClient) -> Result<()>;
}
impl Cli {
#[must_use]
fn stdout(&self) -> StandardStream {
let mut choice: ColorChoice = match self.color {
clap::ColorChoice::Auto => ColorChoice::Auto,
clap::ColorChoice::Always => ColorChoice::Always,
clap::ColorChoice::Never => ColorChoice::Never,
};
if choice == ColorChoice::Auto && !io::stdout().is_terminal() {
choice = ColorChoice::Never;
}
StandardStream::stdout(choice)
}
pub async fn execute(self) -> Result<()> {
let stdout = self.stdout();
let server_client: ServerClient = self.server_cli.into();
self.command.execute(stdout, server_client).await
}
}
#[must_use]
pub fn build_cli() -> clap::Command {
Cli::command()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_cli() {
Cli::command().debug_assert();
}
#[test]
fn test_cli_from_build_cli() {
build_cli().debug_assert();
}
}