wit_spell_check/
checks.rs1use std::path::Path;
2use hunspell_rs::{CheckResult, Hunspell};
3use wit_parser::{Function, Interface, PackageName, UnresolvedPackage};
4
5pub struct WitSpellCheck {
7 hunspell: Hunspell,
8 check_function: bool,
9 check_parameter: bool,
10}
11
12impl WitSpellCheck {
13 pub fn new<P>(directory: P) -> anyhow::Result<Self> where P: AsRef<Path> {
15 let dir = directory.as_ref();
16 let aff = dir.join("en_US.aff");
17 let dic = dir.join("en_US.dic");
18 let mut hun = Hunspell::new(&aff.to_string_lossy(), &dic.to_string_lossy());
19 let custom = std::fs::read_to_string(&dir.join("custom.dic"))?;
22 for line in custom.lines() {
23 if !line.trim().is_empty() {
24 hun.add(line.trim());
25 }
26 }
27 Ok(Self {
28 hunspell: hun,
29 check_function: true,
30 check_parameter: true,
31 })
32 }
33 pub fn check_functions(self, check: bool) -> Self {
35 Self {
36 check_function: check,
37 ..self
38 }
39 }
40 pub fn check_parameters(self, check: bool) -> Self {
42 Self {
43 check_parameter: check,
44 ..self
45 }
46 }
47}
48
49impl WitSpellCheck {
50 pub fn check<P>(&self, directory: P) where P: AsRef<Path> {
52 let package = UnresolvedPackage::parse_dir(directory.as_ref()).unwrap();
53 for (_, interface) in package.interfaces.iter() {
54 for (name, function) in interface.functions.iter() {
55 if self.check_parameter {
56 for (parameter, _) in function.params.iter() {
57 for part in parameter.split("-") {
58 match self.hunspell.check(part) {
59 CheckResult::FoundInDictionary => {}
60 CheckResult::MissingInDictionary => {
61 println!("- parameter may wrong: `{}`", part);
62 println!(" - in function `{}`", name);
63 match &interface.name {
64 Some(s) => {
65 println!(" - in interface `{}`", s);
66 }
67 None => {}
68 }
69 println!(" - in package `{}`", package.name);
70 println!(" - perhaps {:?}", self.hunspell.suggest(part));
71 }
72 }
73 }
74 }
75 }
76 if self.check_function {
77 self.check_function(function, interface, &package.name);
78 }
79 }
80 }
81 }
82 fn check_function(&self, function: &Function, interface: &Interface, package: &PackageName) {
84 let norm = function.name.trim_start_matches("[constructor]").trim_start_matches("[static]").trim_start_matches("[method]");
85 for split in norm.split(".") {
86 for part in split.split("-") {
87 match self.hunspell.check(part) {
88 CheckResult::FoundInDictionary => {}
89 CheckResult::MissingInDictionary => {
90 println!("- function may wrong: `{}`", part);
91 match &interface.name {
92 Some(s) => {
93 println!(" - in interface `{}`", s);
94 }
95 None => {}
96 }
97 println!(" - in package `{}`", package.name);
98 println!(" - perhaps {:?}", self.hunspell.suggest(part));
99 }
100 }
101 }
102 }
103 }
104}