Skip to content

Commit

Permalink
Merge pull request #28 from jeertmans/feature-refactoring
Browse files Browse the repository at this point in the history
chore(lib): refactoring feature usage
  • Loading branch information
jeertmans authored Sep 7, 2022
2 parents c07a671 + 7e619de commit eaaef2d
Show file tree
Hide file tree
Showing 8 changed files with 78 additions and 74 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ 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)
- Added release dates. [#31](https://github.com/jeertmans/languagetool-rust/pull/31)
- Added `#[must_use]` flag to most structures, to please clippy pendantic. [#29](https://github.com/jeertmans/languagetool-rust/pull/21)
- Added `#[must_use]` flag to most structures, to please clippy pendantic. [#29](https://github.com/jeertmans/languagetool-rust/pull/29)
- 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

Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"]
Expand Down
10 changes: 5 additions & 5 deletions src/bin.rs
Original file line number Diff line number Diff line change
@@ -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.
Expand Down Expand Up @@ -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!())
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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,
Expand Down
53 changes: 28 additions & 25 deletions src/lib/check.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
//! 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;
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -157,7 +156,7 @@ impl Serialize for Data {
}
}

#[cfg(feature = "cli")]
#[cfg(feature = "clap")]
impl std::str::FromStr for Data {
type Err = clap::Error;

Expand Down Expand Up @@ -205,7 +204,7 @@ impl Level {
}
}

#[cfg(feature = "cli")]
#[cfg(feature = "clap")]
impl std::str::FromStr for Level {
type Err = clap::Error;

Expand All @@ -221,7 +220,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]
Expand All @@ -235,7 +234,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]
Expand All @@ -246,21 +245,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<String>,
#[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.
///
Expand All @@ -285,14 +284,18 @@ 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<Data>,
#[cfg_attr(
feature = "cli",
all(feature = "clap", feature = "lazy_static", feature = "regex"),
clap(
short = 'l',
long,
default_value = "auto",
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`.
Expand All @@ -301,45 +304,45 @@ pub struct CheckRequest {
#[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<String>,
#[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<String>,
#[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<Vec<String>>,
#[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<String>,
#[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<Vec<String>>,
#[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<Vec<String>>,
#[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<Vec<String>>,
#[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<Vec<String>>,
#[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<Vec<String>>,
#[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::<Level>::new()))]
#[cfg_attr(feature = "clap", clap(long, default_value = "default", value_parser = clap::builder::EnumValueParser::<Level>::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,
Expand Down Expand Up @@ -466,7 +469,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.
Expand Down Expand Up @@ -568,7 +571,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<MoreContext>,
Expand Down Expand Up @@ -726,7 +729,7 @@ impl CheckResponseWithContext {
}
}

#[cfg(feature = "cli")]
#[cfg(feature = "clap")]
impl From<CheckResponseWithContext> for CheckResponse {
#[allow(clippy::needless_borrow)]
fn from(mut resp: CheckResponseWithContext) -> Self {
Expand Down
16 changes: 8 additions & 8 deletions src/lib/docker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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 {
Expand Down
6 changes: 3 additions & 3 deletions src/lib/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down Expand Up @@ -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 =
Expand Down
Loading

0 comments on commit eaaef2d

Please sign in to comment.