feat(config): print a suggestion for unknown fields (#2560)
* feat(config): print a suggestion for unknown fields * Fix typo Co-authored-by: Thomas O'Donnell <andytom@users.noreply.github.com> Co-authored-by: Thomas O'Donnell <andytom@users.noreply.github.com>
This commit is contained in:
parent
a2cdc912e7
commit
8af677c811
|
@ -247,7 +247,7 @@ dependencies = [
|
|||
"ansi_term 0.11.0",
|
||||
"atty",
|
||||
"bitflags 1.2.1",
|
||||
"strsim",
|
||||
"strsim 0.8.0",
|
||||
"textwrap",
|
||||
"unicode-width",
|
||||
"vec_map",
|
||||
|
@ -1614,6 +1614,7 @@ dependencies = [
|
|||
"shadow-rs",
|
||||
"shell-words",
|
||||
"starship_module_config_derive",
|
||||
"strsim 0.10.0",
|
||||
"sys-info",
|
||||
"tempfile",
|
||||
"term_size",
|
||||
|
@ -1628,7 +1629,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "starship_module_config_derive"
|
||||
version = "0.2.0"
|
||||
version = "0.2.1"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote 1.0.9",
|
||||
|
@ -1641,6 +1642,12 @@ version = "0.8.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
||||
|
||||
[[package]]
|
||||
name = "strum"
|
||||
version = "0.8.0"
|
||||
|
|
|
@ -49,7 +49,7 @@ once_cell = "1.7.2"
|
|||
chrono = "0.4.19"
|
||||
sys-info = "0.8.0"
|
||||
byte-unit = "4.0.10"
|
||||
starship_module_config_derive = { version = "0.2.0", path = "starship_module_config_derive" }
|
||||
starship_module_config_derive = { version = "0.2.1", path = "starship_module_config_derive" }
|
||||
yaml-rust = "0.4.5"
|
||||
pest = "2.1.3"
|
||||
pest_derive = "2.1.0"
|
||||
|
@ -67,6 +67,7 @@ notify-rust = { version = "4.3.0", optional = true }
|
|||
semver = "0.11.0"
|
||||
which = "4.1.0"
|
||||
shadow-rs = "0.5.25"
|
||||
strsim = "0.10.0"
|
||||
|
||||
process_control = { version = "3.0.1", features = ["crossbeam-channel"] }
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use crate::{config::ModuleConfig, module::ALL_MODULES};
|
||||
|
||||
use serde::Serialize;
|
||||
use std::cmp::Ordering;
|
||||
|
||||
// On changes please also update the `FullConfig` struct in `mod.rs`
|
||||
#[derive(Clone, Serialize)]
|
||||
|
@ -100,6 +101,31 @@ impl<'a> ModuleConfig<'a> for StarshipRootConfig<'a> {
|
|||
unknown => {
|
||||
if !ALL_MODULES.contains(&unknown) && unknown != "custom" {
|
||||
log::warn!("Unknown config key '{}'", unknown);
|
||||
|
||||
let did_you_mean = &[
|
||||
// Root options
|
||||
"format",
|
||||
"scan_timeout",
|
||||
"command_timeout",
|
||||
"add_newline",
|
||||
// Modules
|
||||
"custom",
|
||||
]
|
||||
.iter()
|
||||
.chain(ALL_MODULES.iter())
|
||||
.filter_map(|field| {
|
||||
let score = strsim::jaro_winkler(unknown, field);
|
||||
(score > 0.8).then(|| (score, field))
|
||||
})
|
||||
.max_by(
|
||||
|(score_a, _field_a), (score_b, _field_b)| {
|
||||
score_a.partial_cmp(score_b).unwrap_or(Ordering::Equal)
|
||||
},
|
||||
);
|
||||
|
||||
if let Some((_score, field)) = did_you_mean {
|
||||
log::warn!("Did you mean '{}'?", field);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "starship_module_config_derive"
|
||||
version = "0.2.0"
|
||||
version = "0.2.1"
|
||||
edition = "2018"
|
||||
authors = ["Matan Kushner <hello@matchai.me>"]
|
||||
homepage = "https://starship.rs"
|
||||
|
|
|
@ -18,6 +18,7 @@ fn impl_module_config(dinput: DeriveInput) -> proc_macro::TokenStream {
|
|||
if let syn::Data::Struct(data) = dinput.data {
|
||||
if let syn::Fields::Named(fields_named) = data.fields {
|
||||
let mut load_tokens = quote! {};
|
||||
let mut fields = quote! {};
|
||||
|
||||
for field in fields_named.named.iter() {
|
||||
let ident = field.ident.as_ref().unwrap();
|
||||
|
@ -26,10 +27,19 @@ fn impl_module_config(dinput: DeriveInput) -> proc_macro::TokenStream {
|
|||
stringify!(#ident) => self.#ident.load_config(v),
|
||||
};
|
||||
|
||||
let new_field = quote! {
|
||||
stringify!(#ident),
|
||||
};
|
||||
|
||||
load_tokens = quote! {
|
||||
#load_tokens
|
||||
#new_load_tokens
|
||||
};
|
||||
|
||||
fields = quote! {
|
||||
#fields
|
||||
#new_field
|
||||
};
|
||||
}
|
||||
|
||||
load_config = quote! {
|
||||
|
@ -40,6 +50,21 @@ fn impl_module_config(dinput: DeriveInput) -> proc_macro::TokenStream {
|
|||
#load_tokens
|
||||
unknown => {
|
||||
::log::warn!("Unknown config key '{}'", unknown);
|
||||
|
||||
let did_you_mean = ::std::array::IntoIter::new([#fields])
|
||||
.filter_map(|field| {
|
||||
let score = ::strsim::jaro_winkler(unknown, field);
|
||||
(score > 0.8).then(|| (score, field))
|
||||
})
|
||||
.max_by(
|
||||
|(score_a, _field_a), (score_b, _field_b)| {
|
||||
score_a.partial_cmp(score_b).unwrap_or(::std::cmp::Ordering::Equal)
|
||||
},
|
||||
);
|
||||
|
||||
if let Some((_score, field)) = did_you_mean {
|
||||
::log::warn!("Did you mean '{}'?", field);
|
||||
}
|
||||
},
|
||||
}
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue