Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Polish configuration support #222

Merged
merged 14 commits into from
Apr 10, 2021
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ typed-arena = "2.0.1"
assert_fs = "1.0"
predicates = "1.0"
criterion = "0.3"
maplit = "1.0"

[profile.dev]
panic = "abort"
Expand Down
2 changes: 1 addition & 1 deletion docs/about.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ See also [benchmarks](../benchsuite/runs).
| Runtime | \- | \- | \- | Python | Python |
| Dictionary | Blacklist | Blacklist | Blacklist | Blacklist | Whitelist |
| Custom Dict | Yes | No | ? | Yes | Yes |
| Per-Lang Dict | No ([#14][def-14]) | No | ? | No | Yes |
| Per-Lang Dict | Yes | No | ? | No | Yes |
| CamelCase | Yes | No | ? | No | Yes |
| snake_case | Yes | No | ? | No | Yes |
| Ignore Hex | Yes | No | ? | No | Yes |
Expand Down
3 changes: 2 additions & 1 deletion docs/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,5 @@ Configuration is read from the following (in precedence order)
| default.locale | --locale | en, en-us, en-gb, en-ca, en-au | English dialect to correct to. |
| default.extend-identifiers | \- | table of strings | Corrections for identifiers. When the correction is blank, the word is never valid. When the correction is the key, the word is always valid. |
| default.extend-words | \- | table of strings | Corrections for identifiers. When the correction is blank, the word is never valid. When the correction is the key, the word is always valid. |
| type.<name>.binary | <varied> | <varied> | See `default.` for child keys. Run with `--type-list` to see available `<name>`s |
| type.<name>.<field> | <varied> | <varied> | See `default.` for child keys. Run with `--type-list` to see available `<name>`s |
| type.<name>.extend_globs | \- | list of strings | File globs for matching `<name>` |
107 changes: 100 additions & 7 deletions src/config.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
use std::collections::HashMap;

#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)]
#[derive(Debug, Clone, Default, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
#[serde(deny_unknown_fields, default)]
#[serde(rename_all = "kebab-case")]
pub struct Config {
pub files: Walk,
pub default: EngineConfig,
#[serde(rename = "type")]
pub type_: std::collections::HashMap<kstring::KString, EngineConfig>,
pub type_: std::collections::HashMap<kstring::KString, TypeEngineConfig>,
#[serde(skip)]
pub overrides: EngineConfig,
}
Expand Down Expand Up @@ -46,10 +46,17 @@ impl Config {
pub fn update(&mut self, source: &Config) {
self.files.update(&source.files);
self.default.update(&source.default);
for (type_name, engine) in source.type_.iter() {
self.type_
.entry(type_name.to_owned())
.or_insert_with(TypeEngineConfig::default)
.update(engine);
}
self.overrides.update(&source.overrides);
}
}

#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)]
#[derive(Debug, Clone, Default, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
#[serde(deny_unknown_fields, default)]
#[serde(rename_all = "kebab-case")]
pub struct Walk {
Expand Down Expand Up @@ -130,7 +137,23 @@ impl Walk {
}
}

#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)]
#[derive(Debug, Clone, Default, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
#[serde(deny_unknown_fields, default)]
#[serde(rename_all = "kebab-case")]
pub struct TypeEngineConfig {
pub extend_glob: Vec<kstring::KString>,
#[serde(flatten)]
pub engine: EngineConfig,
}

impl TypeEngineConfig {
pub fn update(&mut self, source: &TypeEngineConfig) {
self.extend_glob.extend(source.extend_glob.iter().cloned());
self.engine.update(&source.engine);
}
}

#[derive(Debug, Clone, Default, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
#[serde(deny_unknown_fields, default)]
#[serde(rename_all = "kebab-case")]
pub struct EngineConfig {
Expand Down Expand Up @@ -203,7 +226,7 @@ impl EngineConfig {
}
}

#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)]
#[derive(Debug, Clone, Default, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
#[serde(deny_unknown_fields, default)]
#[serde(rename_all = "kebab-case")]
pub struct TokenizerConfig {
Expand Down Expand Up @@ -274,7 +297,7 @@ impl TokenizerConfig {
}
}

#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)]
#[derive(Debug, Clone, Default, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
#[serde(deny_unknown_fields, default)]
#[serde(rename_all = "kebab-case")]
pub struct DictConfig {
Expand Down Expand Up @@ -343,7 +366,7 @@ fn find_project_file(dir: &std::path::Path, names: &[&str]) -> Option<std::path:
None
}

#[derive(Debug, Copy, Clone, serde::Serialize, serde::Deserialize)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "kebab-case")]
pub enum Locale {
En,
Expand Down Expand Up @@ -401,3 +424,73 @@ impl std::fmt::Display for Locale {
}
}
}

#[cfg(test)]
mod test {
use super::*;

#[test]
fn test_from_defaults() {
let null = Config::default();
let defaulted = Config::from_defaults();
assert_ne!(defaulted, null);
assert_ne!(defaulted.files, null.files);
assert_ne!(defaulted.default, null.default);
assert_ne!(defaulted.default.tokenizer, null.default.tokenizer);
assert_ne!(defaulted.default.dict, null.default.dict);
}

#[test]
fn test_update_from_nothing() {
let null = Config::default();
let defaulted = Config::from_defaults();

let mut actual = defaulted.clone();
actual.update(&null);

assert_eq!(actual, defaulted);
}

#[test]
fn test_update_from_defaults() {
let null = Config::default();
let defaulted = Config::from_defaults();

let mut actual = null;
actual.update(&defaulted);

assert_eq!(actual, defaulted);
}

#[test]
fn test_extend_glob_updates() {
let null = TypeEngineConfig::default();
let extended = TypeEngineConfig {
extend_glob: vec!["*.foo".into()],
..Default::default()
};

let mut actual = null;
actual.update(&extended);

assert_eq!(actual, extended);
}

#[test]
fn test_extend_glob_extends() {
let base = TypeEngineConfig {
extend_glob: vec!["*.foo".into()],
..Default::default()
};
let extended = TypeEngineConfig {
extend_glob: vec!["*.bar".into()],
..Default::default()
};

let mut actual = base;
actual.update(&extended);

let expected: Vec<kstring::KString> = vec!["*.foo".into(), "*.bar".into()];
assert_eq!(actual.extend_glob, expected);
}
}
Loading