From 64fd987e80ae058060d08f6c9ee2213a7fa15d0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9rome=20Eertmans?= Date: Wed, 7 Sep 2022 14:01:25 +0200 Subject: [PATCH 1/2] chore(lib): refactoring feature usage --- CHANGELOG.md | 1 + src/bin.rs | 8 ++++---- src/lib/check.rs | 48 +++++++++++++++++++++++------------------------ src/lib/docker.rs | 16 ++++++++-------- src/lib/error.rs | 6 +++--- src/lib/server.rs | 28 +++++++++++++-------------- src/lib/words.rs | 34 ++++++++++++++++----------------- 7 files changed, 71 insertions(+), 70 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 72e3fd9..0cb41a6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Created founding link. [#19](https://github.com/jeertmans/languagetool-rust/pull/19) - Added two related projets. [#21](https://github.com/jeertmans/languagetool-rust/pull/21) +- Changed conditional compilation flags to directly point to dependency, e.g., `"clap"` instead of `"cli"`. [#28](https://github.com/jeertmans/languagetool-rust/pull/28) ### Added diff --git a/src/bin.rs b/src/bin.rs index 29e71d2..3ddc6ce 100644 --- a/src/bin.rs +++ b/src/bin.rs @@ -1,11 +1,11 @@ use clap::{CommandFactory, FromArgMatches}; -#[cfg(feature = "cli-complete")] +#[cfg(feature = "clap-complete")] use clap_complete::{generate, shells}; use languagetool_rust::error::Result; use languagetool_rust::*; use std::io::{BufRead, Write}; -#[cfg(feature = "cli-complete")] +#[cfg(feature = "clap-complete")] pub(crate) static COMPLETIONS_HELP: &str = r"DISCUSSION: Enable tab completion for Bash, Fish, Zsh, or PowerShell Elvish shell completion is currently supported, but not documented below. @@ -157,7 +157,7 @@ fn build_cli() -> clap::Command<'static> { .author(clap::crate_authors!()), ); - #[cfg(feature = "cli-complete")] + #[cfg(feature = "clap-complete")] let command = command.subcommand( clap::Command::new("completions") .author(clap::crate_authors!()) @@ -237,7 +237,7 @@ async fn try_main() -> Result<()> { let mut resp = client.check(&req).await?; - #[cfg(feature = "cli")] + #[cfg(feature = "clap")] if req.more_context { use crate::check::CheckResponseWithContext; let text = req.get_text(); diff --git a/src/lib/check.rs b/src/lib/check.rs index 04546a4..e3c7a37 100644 --- a/src/lib/check.rs +++ b/src/lib/check.rs @@ -1,7 +1,7 @@ //! Structures for `check` requests and responses. use crate::error::Error; -#[cfg(feature = "cli")] +#[cfg(feature = "clap")] use clap::Parser; #[cfg(feature = "lazy_static")] use lazy_static::lazy_static; @@ -154,7 +154,7 @@ impl Serialize for Data { } } -#[cfg(feature = "cli")] +#[cfg(feature = "clap")] impl std::str::FromStr for Data { type Err = clap::Error; @@ -201,7 +201,7 @@ impl Level { } } -#[cfg(feature = "cli")] +#[cfg(feature = "clap")] impl std::str::FromStr for Level { type Err = clap::Error; @@ -217,7 +217,7 @@ impl std::str::FromStr for Level { } } -#[cfg(feature = "cli")] +#[cfg(feature = "clap")] impl clap::ValueEnum for Level { fn value_variants<'a>() -> &'a [Self] { &[Self::Default, Self::Picky] @@ -231,7 +231,7 @@ impl clap::ValueEnum for Level { } } -#[cfg_attr(feature = "cli", derive(Parser))] +#[cfg_attr(feature = "clap", derive(Parser))] #[derive(Clone, Deserialize, Debug, Default, PartialEq, Eq, Serialize)] #[serde(rename_all = "camelCase")] #[non_exhaustive] @@ -242,21 +242,21 @@ impl clap::ValueEnum for Level { /// The structure below tries to follow as closely as possible the JSON API described /// [here](https://languagetool.org/http-api/swagger-ui/#!/default/post_check). pub struct CheckRequest { - #[cfg(all(feature = "cli", feature = "annotate"))] + #[cfg(all(feature = "clap", feature = "annotate"))] #[clap(short = 'r', long, takes_value = false)] #[serde(skip_serializing)] /// If present, raw JSON output will be printed instead of annotated text. pub raw: bool, - #[cfg(feature = "cli")] + #[cfg(feature = "clap")] #[clap(short = 'm', long, takes_value = false)] #[serde(skip_serializing)] /// If present, more context (i.e., line number and line offset) will be added to response. pub more_context: bool, - #[cfg_attr(feature = "cli", clap(short = 't', long, conflicts_with = "data",))] + #[cfg_attr(feature = "clap", clap(short = 't', long, conflicts_with = "data",))] #[serde(skip_serializing_if = "Option::is_none")] /// The text to be checked. This or 'data' is required. pub text: Option, - #[cfg_attr(feature = "cli", clap(short = 'd', long, conflicts_with = "text"))] + #[cfg_attr(feature = "clap", clap(short = 'd', long, conflicts_with = "text"))] #[serde(skip_serializing_if = "Option::is_none")] /// The text to be checked, given as a JSON document that specifies what's text and what's markup. This or 'text' is required. /// @@ -281,7 +281,7 @@ pub struct CheckRequest { /// The 'data' feature is not limited to HTML or XML, it can be used for any kind of markup. Entities will need to be expanded in this input. pub data: Option, #[cfg_attr( - feature = "cli", + feature = "clap", clap( short = 'l', long, @@ -293,49 +293,49 @@ pub struct CheckRequest { /// /// For languages with variants (English, German, Portuguese) spell checking will only be activated when you specify the variant, e.g. `en-GB` instead of just `en`. pub language: String, - #[cfg_attr(feature = "cli", clap(short = 'u', long, requires = "api_key"))] + #[cfg_attr(feature = "clap", clap(short = 'u', long, requires = "api_key"))] #[serde(skip_serializing_if = "Option::is_none")] /// Set to get Premium API access: Your username/email as used to log in at languagetool.org. pub username: Option, - #[cfg_attr(feature = "cli", clap(short = 'k', long, requires = "username"))] + #[cfg_attr(feature = "clap", clap(short = 'k', long, requires = "username"))] #[serde(skip_serializing_if = "Option::is_none")] /// Set to get Premium API access: [your API key](https://languagetool.org/editor/settings/api) pub api_key: Option, - #[cfg_attr(feature = "cli", clap(long, multiple_values = true))] + #[cfg_attr(feature = "clap", clap(long, multiple_values = true))] #[serde(skip_serializing_if = "Option::is_none")] /// Comma-separated list of dictionaries to include words from; uses special default dictionary if this is unset pub dicts: Option>, - #[cfg_attr(feature = "cli", clap(long))] + #[cfg_attr(feature = "clap", clap(long))] #[serde(skip_serializing_if = "Option::is_none")] /// A language code of the user's native language, enabling false friends checks for some language pairs. pub mother_tongue: Option, - #[cfg_attr(feature = "cli", clap(long, multiple_values = true))] + #[cfg_attr(feature = "clap", clap(long, multiple_values = true))] #[serde(skip_serializing_if = "Option::is_none")] /// Comma-separated list of preferred language variants. /// /// The language detector used with `language=auto` can detect e.g. English, but it cannot decide whether British English or American English is used. Thus this parameter can be used to specify the preferred variants like `en-GB` and `de-AT`. Only available with `language=auto`. You should set variants for at least German and English, as otherwise the spell checking will not work for those, as no spelling dictionary can be selected for just `en` or `de`. pub preferred_variants: Option>, - #[cfg_attr(feature = "cli", clap(long, multiple_values = true))] + #[cfg_attr(feature = "clap", clap(long, multiple_values = true))] #[serde(skip_serializing_if = "Option::is_none")] /// IDs of rules to be enabled, comma-separated pub enabled_rules: Option>, - #[cfg_attr(feature = "cli", clap(long, multiple_values = true))] + #[cfg_attr(feature = "clap", clap(long, multiple_values = true))] #[serde(skip_serializing_if = "Option::is_none")] /// IDs of rules to be disabled, comma-separated pub disabled_rules: Option>, - #[cfg_attr(feature = "cli", clap(long, multiple_values = true))] + #[cfg_attr(feature = "clap", clap(long, multiple_values = true))] #[serde(skip_serializing_if = "Option::is_none")] /// IDs of categories to be enabled, comma-separated pub enabled_categories: Option>, - #[cfg_attr(feature = "cli", clap(long, multiple_values = true))] + #[cfg_attr(feature = "clap", clap(long, multiple_values = true))] #[serde(skip_serializing_if = "Option::is_none")] /// IDs of categories to be disabled, comma-separated pub disabled_categories: Option>, - #[cfg_attr(feature = "cli", clap(long, takes_value = false))] + #[cfg_attr(feature = "clap", clap(long, takes_value = false))] #[serde(skip_serializing_if = "is_false")] /// If true, only the rules and categories whose IDs are specified with `enabledRules` or `enabledCategories` are enabled. pub enabled_only: bool, - #[cfg_attr(feature = "cli", clap(long, default_value = "default", value_parser = clap::builder::EnumValueParser::::new()))] + #[cfg_attr(feature = "clap", clap(long, default_value = "default", value_parser = clap::builder::EnumValueParser::::new()))] #[serde(skip_serializing_if = "Level::is_default")] /// If set to `picky`, additional rules will be activated, i.e. rules that you might only find useful when checking formal text. pub level: Level, @@ -457,7 +457,7 @@ pub struct Context { pub text: String, } -#[cfg(feature = "cli")] +#[cfg(feature = "clap")] #[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)] #[non_exhaustive] /// More context, post-processed in check response. @@ -559,7 +559,7 @@ pub struct Match { pub length: usize, /// Error message pub message: String, - #[cfg(feature = "cli")] + #[cfg(feature = "clap")] #[serde(skip_serializing_if = "Option::is_none")] /// More context to match, post-processed using original text pub more_context: Option, @@ -714,7 +714,7 @@ impl CheckResponseWithContext { } } -#[cfg(feature = "cli")] +#[cfg(feature = "clap")] impl From for CheckResponse { #[allow(clippy::needless_borrow)] fn from(mut resp: CheckResponseWithContext) -> Self { diff --git a/src/lib/docker.rs b/src/lib/docker.rs index ee96a4c..6a51858 100644 --- a/src/lib/docker.rs +++ b/src/lib/docker.rs @@ -2,16 +2,16 @@ //! applications. use crate::error::{exit_status_error, Result}; -#[cfg(feature = "cli")] +#[cfg(feature = "clap")] use clap::Parser; use std::process::{Command, Output, Stdio}; -#[cfg_attr(feature = "cli", derive(Parser))] +#[cfg_attr(feature = "clap", derive(Parser))] #[derive(Debug, Clone)] /// Commands to pull, start and stop a `LanguageTool` container using Docker. pub struct Docker { #[cfg_attr( - feature = "cli", + feature = "clap", clap( default_value = "erikvl87/languagetool", env = "LANGUAGETOOL_DOCKER_IMAGE" @@ -20,7 +20,7 @@ pub struct Docker { /// Image or repository from a registry. name: String, #[cfg_attr( - feature = "cli", + feature = "clap", clap( short = 'b', long, @@ -31,13 +31,13 @@ pub struct Docker { /// Path to Docker's binaries. bin: String, #[cfg_attr( - feature = "cli", + feature = "clap", clap(long, default_value = "languagetool", env = "LANGUAGETOOL_DOCKER_NAME") )] /// Name assigned to the container. container_name: String, #[cfg_attr( - feature = "cli", + feature = "clap", clap( short = 'p', long, @@ -47,12 +47,12 @@ pub struct Docker { )] /// Publish a container's port(s) to the host. port: String, - #[cfg_attr(feature = "cli", clap(subcommand))] + #[cfg_attr(feature = "clap", clap(subcommand))] /// Docker action. action: Action, } -#[cfg_attr(feature = "cli", derive(clap::Subcommand))] +#[cfg_attr(feature = "clap", derive(clap::Subcommand))] #[derive(Clone, Debug)] /// Enumerate supported Docker actions. enum Action { diff --git a/src/lib/error.rs b/src/lib/error.rs index c560a2f..d817cf6 100644 --- a/src/lib/error.rs +++ b/src/lib/error.rs @@ -4,7 +4,7 @@ use std::process::ExitStatus; /// Enumeration of all possible error types. #[derive(Debug, thiserror::Error)] pub enum Error { - #[cfg(feature = "cli")] + #[cfg(feature = "clap")] #[error(transparent)] /// Error from the command line parsing (see [clap::Error]). Cli(#[from] clap::Error), @@ -80,10 +80,10 @@ pub(crate) fn exit_status_error(exit_status: &ExitStatus) -> Result<()> { mod tests { use crate::error::Error; - #[cfg(feature = "cli")] + #[cfg(feature = "clap")] use clap::Command; - #[cfg(feature = "cli")] + #[cfg(feature = "clap")] #[test] fn test_error_cli() { let result = diff --git a/src/lib/server.rs b/src/lib/server.rs index 3716120..acd8823 100644 --- a/src/lib/server.rs +++ b/src/lib/server.rs @@ -12,7 +12,7 @@ use annotate_snippets::{ display_list::{DisplayList, FormatOptions}, snippet::{Annotation, AnnotationType, Slice, Snippet, SourceAnnotation}, }; -#[cfg(feature = "cli")] +#[cfg(feature = "clap")] use clap::{CommandFactory, FromArgMatches, Parser}; use reqwest::Client; use serde::{Deserialize, Serialize}; @@ -180,28 +180,28 @@ impl Default for ConfigFile { } } -#[cfg_attr(feature = "cli", derive(Parser))] +#[cfg_attr(feature = "clap", derive(Parser))] #[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] #[non_exhaustive] /// Server parameters that are to be used when instantiating a `LanguageTool` server pub struct ServerParameters { - #[cfg_attr(feature = "cli", clap(long))] + #[cfg_attr(feature = "clap", clap(long))] config: Option, - #[cfg_attr(feature = "cli", clap(short = 'p', long, name = "PRT", default_value = "8081", validator = is_port))] + #[cfg_attr(feature = "clap", clap(short = 'p', long, name = "PRT", default_value = "8081", validator = is_port))] port: String, - #[cfg_attr(feature = "cli", clap(long, takes_value = false))] + #[cfg_attr(feature = "clap", clap(long, takes_value = false))] public: bool, - #[cfg_attr(feature = "cli", clap(long, name = "ORIGIN"))] + #[cfg_attr(feature = "clap", clap(long, name = "ORIGIN"))] allow_origin: Option, - #[cfg_attr(feature = "cli", clap(short = 'v', long, takes_value = false))] + #[cfg_attr(feature = "clap", clap(short = 'v', long, takes_value = false))] verbose: bool, - #[cfg_attr(feature = "cli", clap(long, takes_value = false))] + #[cfg_attr(feature = "clap", clap(long, takes_value = false))] #[serde(rename = "languageModel")] language_model: Option, - #[cfg_attr(feature = "cli", clap(long, takes_value = false))] + #[cfg_attr(feature = "clap", clap(long, takes_value = false))] #[serde(rename = "word2vecModel")] word2vec_model: Option, - #[cfg_attr(feature = "cli", clap(long, takes_value = false))] + #[cfg_attr(feature = "clap", clap(long, takes_value = false))] #[serde(rename = "premiumAlways")] premium_always: bool, } @@ -221,7 +221,7 @@ impl Default for ServerParameters { } } -#[cfg_attr(feature = "cli", derive(Parser))] +#[cfg_attr(feature = "clap", derive(Parser))] #[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)] /// Hostname and (optional) port to connect to a `LanguageTool` server. /// @@ -241,7 +241,7 @@ pub struct ServerCli { )] pub hostname: String, /// Server's port number, with the empty string referring to no specific port - #[cfg_attr(feature = "cli", clap(short = 'p', long, name = "PRT", default_value = "", validator = is_port, env = "LANGUAGETOOL_PORT"))] + #[cfg_attr(feature = "clap", clap(short = 'p', long, name = "PRT", default_value = "", validator = is_port, env = "LANGUAGETOOL_PORT"))] pub port: String, } @@ -323,7 +323,7 @@ impl ServerClient { cli.into() } - #[cfg(feature = "cli")] + #[cfg(feature = "clap")] /// This function has the same sementics as [`ServerCli::from_arg_matches`] pub fn from_arg_matches(matches: &clap::ArgMatches) -> Result { let params = ServerCli::from_arg_matches(matches)?; @@ -331,7 +331,7 @@ impl ServerClient { } /// This function has the same semantics as [`ServerCli::command`] - #[cfg(feature = "cli")] + #[cfg(feature = "clap")] pub fn command<'help>() -> clap::Command<'help> { ServerCli::command() } diff --git a/src/lib/words.rs b/src/lib/words.rs index d2f8f91..db4e421 100644 --- a/src/lib/words.rs +++ b/src/lib/words.rs @@ -1,6 +1,6 @@ //! Structures for `words` requests and responses. -#[cfg(feature = "cli")] +#[cfg(feature = "clap")] use clap::Parser; use serde::{Deserialize, Serialize}; @@ -25,76 +25,76 @@ pub fn is_word(v: &str) -> Result<(), String> { )) } -#[cfg_attr(feature = "cli", derive(Parser))] +#[cfg_attr(feature = "clap", derive(Parser))] #[derive(Clone, Debug, Default, PartialEq, Eq, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] #[non_exhaustive] /// Login arguments required by the API. pub struct LoginArgs { - #[cfg_attr(feature = "cli", clap(short = 'u', long, required = true))] + #[cfg_attr(feature = "clap", clap(short = 'u', long, required = true))] /// Your username as used to log in at languagetool.org. pub username: String, - #[cfg_attr(feature = "cli", clap(short = 'k', long, required = true))] + #[cfg_attr(feature = "clap", clap(short = 'k', long, required = true))] /// [Your API key](https://languagetool.org/editor/settings/api) pub api_key: String, } -#[cfg_attr(feature = "cli", derive(Parser))] +#[cfg_attr(feature = "clap", derive(Parser))] #[derive(Clone, Debug, Default, PartialEq, Eq, Deserialize, Serialize)] #[non_exhaustive] /// LanguageTool GET words request. /// /// List words in the user's personal dictionaries. pub struct WordsRequest { - #[cfg_attr(feature = "cli", clap(long, default_value = "0"))] + #[cfg_attr(feature = "clap", clap(long, default_value = "0"))] /// Offset of where to start in the list of words. offset: isize, - #[cfg_attr(feature = "cli", clap(long, default_value = "10"))] + #[cfg_attr(feature = "clap", clap(long, default_value = "10"))] /// Maximum number of words to return. pub limit: isize, - #[cfg_attr(feature = "cli", clap(flatten))] + #[cfg_attr(feature = "clap", clap(flatten))] /// Login arguments pub login: LoginArgs, - #[cfg_attr(feature = "cli", clap(long))] + #[cfg_attr(feature = "clap", clap(long))] #[serde(skip_serializing_if = "Option::is_none")] /// Comma-separated list of dictionaries to include words from; uses special default dictionary if this is unset pub dicts: Option>, } -#[cfg_attr(feature = "cli", derive(Parser))] +#[cfg_attr(feature = "clap", derive(Parser))] #[derive(Clone, Debug, Default, PartialEq, Eq, Deserialize, Serialize)] #[non_exhaustive] /// LanguageTool POST words add request. /// /// Add a word to one of the user's personal dictionaries. Please note that this feature is considered to be used for personal dictionaries which must not contain more than 500 words. If this is an issue for you, please contact us. pub struct WordsAddRequest { - #[cfg_attr(feature = "cli", clap(required = true, validator = is_word))] + #[cfg_attr(feature = "clap", clap(required = true, validator = is_word))] /// The word to be added. Must not be a phrase, i.e. cannot contain white space. The word is added to a global dictionary that applies to all languages. pub word: String, - #[cfg_attr(feature = "cli", clap(flatten))] + #[cfg_attr(feature = "clap", clap(flatten))] /// Login arguments pub login: LoginArgs, - #[cfg_attr(feature = "cli", clap(long))] + #[cfg_attr(feature = "clap", clap(long))] #[serde(skip_serializing_if = "Option::is_none")] /// Name of the dictionary to add the word to; non-existent dictionaries are created after /// calling this; if unset, adds to special default dictionary dict: Option, } -#[cfg_attr(feature = "cli", derive(Parser))] +#[cfg_attr(feature = "clap", derive(Parser))] #[derive(Clone, Debug, Default, PartialEq, Eq, Deserialize, Serialize)] #[non_exhaustive] /// LanguageTool POST words delete request. /// /// Remove a word from one of the user's personal dictionaries. pub struct WordsDeleteRequest { - #[cfg_attr(feature = "cli", clap(required = true, validator = is_word))] + #[cfg_attr(feature = "clap", clap(required = true, validator = is_word))] /// The word to be removed. pub word: String, - #[cfg_attr(feature = "cli", clap(flatten))] + #[cfg_attr(feature = "clap", clap(flatten))] /// Login arguments pub login: LoginArgs, - #[cfg_attr(feature = "cli", clap(long))] + #[cfg_attr(feature = "clap", clap(long))] #[serde(skip_serializing_if = "Option::is_none")] /// Name of the dictionary to add the word to; non-existent dictionaries are created after /// calling this; if unset, adds to special default dictionary From f5afb1dbe95a6229fcc17214917f2f3325d25018 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9rome=20Eertmans?= Date: Wed, 7 Sep 2022 14:30:07 +0200 Subject: [PATCH 2/2] fix(lib): feature flags that blocked compilation --- Cargo.toml | 2 +- src/bin.rs | 8 ++++---- src/lib/check.rs | 9 ++++++--- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 0eb5ed2..7eb727c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,7 +38,7 @@ annotate = ["annotate-snippets"] cli = ["atty", "clap", "lazy_static", "regex", "tokio"] cli-complete = ["cli", "clap_complete"] docker = [] -full = ["annotate", "cli", "docker", "unstable", "cli-complete"] +full = ["annotate", "cli-complete", "docker", "unstable"] native-tls = ["reqwest/native-tls"] native-tls-vendored = ["reqwest/native-tls-vendored"] diff --git a/src/bin.rs b/src/bin.rs index 3ddc6ce..0f620b0 100644 --- a/src/bin.rs +++ b/src/bin.rs @@ -1,11 +1,11 @@ use clap::{CommandFactory, FromArgMatches}; -#[cfg(feature = "clap-complete")] +#[cfg(feature = "clap_complete")] use clap_complete::{generate, shells}; use languagetool_rust::error::Result; use languagetool_rust::*; use std::io::{BufRead, Write}; -#[cfg(feature = "clap-complete")] +#[cfg(feature = "clap_complete")] pub(crate) static COMPLETIONS_HELP: &str = r"DISCUSSION: Enable tab completion for Bash, Fish, Zsh, or PowerShell Elvish shell completion is currently supported, but not documented below. @@ -157,7 +157,7 @@ fn build_cli() -> clap::Command<'static> { .author(clap::crate_authors!()), ); - #[cfg(feature = "clap-complete")] + #[cfg(feature = "clap_complete")] let command = command.subcommand( clap::Command::new("completions") .author(clap::crate_authors!()) @@ -295,7 +295,7 @@ async fn try_main() -> Result<()> { Some(("docker", sub_matches)) => Docker::from_arg_matches(sub_matches)? .run_action() .map(|_| ())?, - #[cfg(feature = "cli-complete")] + #[cfg(feature = "clap_complete")] Some(("completions", sub_matches)) => match sub_matches.value_of("shell").unwrap() { "bash" => generate( shells::Bash, diff --git a/src/lib/check.rs b/src/lib/check.rs index e3c7a37..a2628db 100644 --- a/src/lib/check.rs +++ b/src/lib/check.rs @@ -1,6 +1,5 @@ //! Structures for `check` requests and responses. -use crate::error::Error; #[cfg(feature = "clap")] use clap::Parser; #[cfg(feature = "lazy_static")] @@ -61,7 +60,7 @@ pub fn is_language_code(v: &str) -> crate::error::Result<()> { if v == "auto" || RE.is_match(v) { Ok(()) } else { - Err(Error::InvalidValue { + Err(crate::error::Error::InvalidValue { body: format!( "The value should be `auto` or match regex pattern: {}", RE.as_str() @@ -281,7 +280,7 @@ pub struct CheckRequest { /// The 'data' feature is not limited to HTML or XML, it can be used for any kind of markup. Entities will need to be expanded in this input. pub data: Option, #[cfg_attr( - feature = "clap", + all(feature = "clap", feature = "lazy_static", feature = "regex"), clap( short = 'l', long, @@ -289,6 +288,10 @@ pub struct CheckRequest { validator = is_language_code ) )] + #[cfg_attr( + all(feature = "clap", not(all(feature = "lazy_static", feature = "regex"))), + clap(short = 'l', long, default_value = "auto",) + )] /// A language code like `en-US`, `de-DE`, `fr`, or `auto` to guess the language automatically (see `preferredVariants` below). /// /// For languages with variants (English, German, Portuguese) spell checking will only be activated when you specify the variant, e.g. `en-GB` instead of just `en`.