Use strum
crate to derive enum↔string conversions
type: reform
This commit is contained in:
parent
6996d1a3ea
commit
362a81d42f
20
Cargo.lock
generated
20
Cargo.lock
generated
|
@ -342,6 +342,8 @@ dependencies = [
|
||||||
"snafu",
|
"snafu",
|
||||||
"static_assertions",
|
"static_assertions",
|
||||||
"structopt",
|
"structopt",
|
||||||
|
"strum",
|
||||||
|
"strum_macros",
|
||||||
"syn",
|
"syn",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
"temptree",
|
"temptree",
|
||||||
|
@ -778,6 +780,24 @@ dependencies = [
|
||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "strum"
|
||||||
|
version = "0.18.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "57bd81eb48f4c437cadc685403cad539345bf703d78e63707418431cecd4522b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "strum_macros"
|
||||||
|
version = "0.18.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "87c85aa3f8ea653bfd3ddf25f7ee357ee4d204731f6aa9ad04002306f6e2774c"
|
||||||
|
dependencies = [
|
||||||
|
"heck",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "1.0.16"
|
version = "1.0.16"
|
||||||
|
|
|
@ -32,6 +32,8 @@ serde_with = "1.4.0"
|
||||||
sha1 = "0.6.0"
|
sha1 = "0.6.0"
|
||||||
snafu = "0.6.0"
|
snafu = "0.6.0"
|
||||||
static_assertions = "1.0.0"
|
static_assertions = "1.0.0"
|
||||||
|
strum = "0.18.0"
|
||||||
|
strum_macros = "0.18.0"
|
||||||
syn = "1.0.14"
|
syn = "1.0.14"
|
||||||
tempfile = "3.0.0"
|
tempfile = "3.0.0"
|
||||||
unicode-width = "0.1.0"
|
unicode-width = "0.1.0"
|
||||||
|
|
|
@ -4,7 +4,7 @@ pub(crate) use std::{
|
||||||
char,
|
char,
|
||||||
cmp::{Ordering, Reverse},
|
cmp::{Ordering, Reverse},
|
||||||
collections::{BTreeMap, BTreeSet, HashMap, HashSet},
|
collections::{BTreeMap, BTreeSet, HashMap, HashSet},
|
||||||
convert::{Infallible, TryInto},
|
convert::TryInto,
|
||||||
env,
|
env,
|
||||||
ffi::{OsStr, OsString},
|
ffi::{OsStr, OsString},
|
||||||
fmt::{self, Display, Formatter},
|
fmt::{self, Display, Formatter},
|
||||||
|
@ -39,6 +39,8 @@ pub(crate) use structopt::{
|
||||||
clap::{AppSettings, ArgSettings},
|
clap::{AppSettings, ArgSettings},
|
||||||
StructOpt,
|
StructOpt,
|
||||||
};
|
};
|
||||||
|
pub(crate) use strum::VariantNames;
|
||||||
|
pub(crate) use strum_macros::{EnumString, EnumVariantNames, IntoStaticStr};
|
||||||
pub(crate) use unicode_width::UnicodeWidthStr;
|
pub(crate) use unicode_width::UnicodeWidthStr;
|
||||||
pub(crate) use url::{Host, Url};
|
pub(crate) use url::{Host, Url};
|
||||||
pub(crate) use walkdir::WalkDir;
|
pub(crate) use walkdir::WalkDir;
|
||||||
|
|
60
src/lint.rs
60
src/lint.rs
|
@ -1,6 +1,9 @@
|
||||||
use crate::common::*;
|
use crate::common::*;
|
||||||
|
|
||||||
#[derive(Eq, PartialEq, Debug, Copy, Clone, Ord, PartialOrd)]
|
#[derive(
|
||||||
|
Eq, PartialEq, Debug, Copy, Clone, Ord, PartialOrd, EnumVariantNames, IntoStaticStr, EnumString,
|
||||||
|
)]
|
||||||
|
#[strum(serialize_all = "kebab-case")]
|
||||||
pub(crate) enum Lint {
|
pub(crate) enum Lint {
|
||||||
PrivateTrackerless,
|
PrivateTrackerless,
|
||||||
SmallPieceLength,
|
SmallPieceLength,
|
||||||
|
@ -8,36 +11,8 @@ pub(crate) enum Lint {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Lint {
|
impl Lint {
|
||||||
const PRIVATE_TRACKERLESS: &'static str = "private-trackerless";
|
|
||||||
const SMALL_PIECE_LENGTH: &'static str = "small-piece-length";
|
|
||||||
const UNEVEN_PIECE_LENGTH: &'static str = "uneven-piece-length";
|
|
||||||
pub(crate) const VALUES: &'static [&'static str] = &[
|
|
||||||
Self::PRIVATE_TRACKERLESS,
|
|
||||||
Self::SMALL_PIECE_LENGTH,
|
|
||||||
Self::UNEVEN_PIECE_LENGTH,
|
|
||||||
];
|
|
||||||
|
|
||||||
pub(crate) fn name(self) -> &'static str {
|
pub(crate) fn name(self) -> &'static str {
|
||||||
match self {
|
self.into()
|
||||||
Self::PrivateTrackerless => Self::PRIVATE_TRACKERLESS,
|
|
||||||
Self::SmallPieceLength => Self::SMALL_PIECE_LENGTH,
|
|
||||||
Self::UnevenPieceLength => Self::UNEVEN_PIECE_LENGTH,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FromStr for Lint {
|
|
||||||
type Err = Error;
|
|
||||||
|
|
||||||
fn from_str(text: &str) -> Result<Self, Self::Err> {
|
|
||||||
match text.replace('_', "-").to_lowercase().as_str() {
|
|
||||||
Self::PRIVATE_TRACKERLESS => Ok(Self::PrivateTrackerless),
|
|
||||||
Self::SMALL_PIECE_LENGTH => Ok(Self::SmallPieceLength),
|
|
||||||
Self::UNEVEN_PIECE_LENGTH => Ok(Self::UnevenPieceLength),
|
|
||||||
_ => Err(Error::LintUnknown {
|
|
||||||
text: text.to_string(),
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,22 +26,24 @@ impl Display for Lint {
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn variants() {
|
||||||
|
assert_eq!(
|
||||||
|
Lint::VARIANTS,
|
||||||
|
&[
|
||||||
|
"private-trackerless",
|
||||||
|
"small-piece-length",
|
||||||
|
"uneven-piece-length"
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn from_str_ok() {
|
fn from_str_ok() {
|
||||||
assert_eq!(
|
|
||||||
Lint::UnevenPieceLength,
|
|
||||||
"uneven_piece_length".parse().unwrap()
|
|
||||||
);
|
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Lint::UnevenPieceLength,
|
Lint::UnevenPieceLength,
|
||||||
"uneven-piece-length".parse().unwrap()
|
"uneven-piece-length".parse().unwrap()
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
Lint::UnevenPieceLength,
|
|
||||||
"UNEVEN-piece-length".parse().unwrap()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -74,6 +51,7 @@ mod tests {
|
||||||
fn case(text: &str, value: Lint) {
|
fn case(text: &str, value: Lint) {
|
||||||
assert_eq!(value, text.parse().unwrap());
|
assert_eq!(value, text.parse().unwrap());
|
||||||
assert_eq!(value.name(), text);
|
assert_eq!(value.name(), text);
|
||||||
|
assert_eq!(value.to_string(), value.name());
|
||||||
}
|
}
|
||||||
|
|
||||||
case("private-trackerless", Lint::PrivateTrackerless);
|
case("private-trackerless", Lint::PrivateTrackerless);
|
||||||
|
@ -85,7 +63,7 @@ mod tests {
|
||||||
fn from_str_err() {
|
fn from_str_err() {
|
||||||
assert_matches!(
|
assert_matches!(
|
||||||
"foo".parse::<Lint>(),
|
"foo".parse::<Lint>(),
|
||||||
Err(Error::LintUnknown { text }) if text == "foo"
|
Err(strum::ParseError::VariantNotFound)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,9 +14,8 @@ pub(crate) struct Options {
|
||||||
#[structopt(
|
#[structopt(
|
||||||
long = "color",
|
long = "color",
|
||||||
value_name = "WHEN",
|
value_name = "WHEN",
|
||||||
default_value = UseColor::AUTO,
|
default_value = UseColor::Auto.into(),
|
||||||
set = ArgSettings::CaseInsensitive,
|
possible_values = UseColor::VARIANTS,
|
||||||
possible_values = UseColor::VALUES,
|
|
||||||
help = "Print colorful output according to `WHEN`. When `auto`, the default, colored output \
|
help = "Print colorful output according to `WHEN`. When `auto`, the default, colored output \
|
||||||
is only enabled if imdl detects that it is connected to a terminal, the `NO_COLOR` \
|
is only enabled if imdl detects that it is connected to a terminal, the `NO_COLOR` \
|
||||||
environment variable is not set, and the `TERM` environment variable is not set to \
|
environment variable is not set, and the `TERM` environment variable is not set to \
|
||||||
|
|
|
@ -22,8 +22,7 @@ pub(crate) struct Create {
|
||||||
long = "allow",
|
long = "allow",
|
||||||
short = "A",
|
short = "A",
|
||||||
value_name = "LINT",
|
value_name = "LINT",
|
||||||
possible_values = Lint::VALUES,
|
possible_values = Lint::VARIANTS,
|
||||||
set(ArgSettings::CaseInsensitive),
|
|
||||||
help = "Allow `LINT`. Lints check for conditions which, although permitted, are not usually \
|
help = "Allow `LINT`. Lints check for conditions which, although permitted, are not usually \
|
||||||
desirable. For example, piece length can be any non-zero value, but probably \
|
desirable. For example, piece length can be any non-zero value, but probably \
|
||||||
shouldn't be below 16 KiB. The lint `small-piece-size` checks for this, and \
|
shouldn't be below 16 KiB. The lint `small-piece-size` checks for this, and \
|
||||||
|
@ -2254,7 +2253,7 @@ Content Size 9 bytes
|
||||||
"foo",
|
"foo",
|
||||||
"--private",
|
"--private",
|
||||||
"--allow",
|
"--allow",
|
||||||
"private-trackerLESS",
|
"private-trackerless",
|
||||||
],
|
],
|
||||||
tree: {
|
tree: {
|
||||||
foo: "",
|
foo: "",
|
||||||
|
|
|
@ -1,52 +1,26 @@
|
||||||
use crate::common::*;
|
use crate::common::*;
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
#[derive(Copy, Clone, Debug, PartialEq, EnumVariantNames, EnumString, IntoStaticStr)]
|
||||||
|
#[strum(serialize_all = "kebab-case")]
|
||||||
pub(crate) enum UseColor {
|
pub(crate) enum UseColor {
|
||||||
Auto,
|
Auto,
|
||||||
Always,
|
Always,
|
||||||
Never,
|
Never,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UseColor {
|
|
||||||
pub(crate) const ALWAYS: &'static str = "always";
|
|
||||||
pub(crate) const AUTO: &'static str = "auto";
|
|
||||||
pub(crate) const NEVER: &'static str = "never";
|
|
||||||
pub(crate) const VALUES: &'static [&'static str] = &[Self::AUTO, Self::ALWAYS, Self::NEVER];
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FromStr for UseColor {
|
|
||||||
type Err = Infallible;
|
|
||||||
|
|
||||||
fn from_str(text: &str) -> Result<Self, Self::Err> {
|
|
||||||
match text.to_lowercase().as_str() {
|
|
||||||
Self::AUTO => Ok(Self::Auto),
|
|
||||||
Self::ALWAYS => Ok(Self::Always),
|
|
||||||
Self::NEVER => Ok(Self::Never),
|
|
||||||
_ => unreachable!(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn variants() {
|
||||||
|
assert_eq!(UseColor::VARIANTS, &["auto", "always", "never"]);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn from_str() {
|
fn from_str() {
|
||||||
assert_eq!(UseColor::Auto, UseColor::AUTO.parse().unwrap());
|
assert_eq!(UseColor::Auto, "auto".parse().unwrap());
|
||||||
assert_eq!(UseColor::Always, UseColor::ALWAYS.parse().unwrap());
|
assert_eq!(UseColor::Always, "always".parse().unwrap());
|
||||||
assert_eq!(UseColor::Never, UseColor::NEVER.parse().unwrap());
|
assert_eq!(UseColor::Never, "never".parse().unwrap());
|
||||||
assert_eq!(
|
|
||||||
UseColor::Auto,
|
|
||||||
UseColor::AUTO.to_uppercase().parse().unwrap()
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
UseColor::Always,
|
|
||||||
UseColor::ALWAYS.to_uppercase().parse().unwrap()
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
UseColor::Never,
|
|
||||||
UseColor::NEVER.to_uppercase().parse().unwrap()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user