Repository: crate-ci/typos (rust)

Issue:
WRONLY should not be corrected
`O_WRONLY` should be ignored by default as it is a standard constant in libc.

Pull request description:
fix(cli): Dont correct O_WRONLY
Realized we could just hard code this for now rather creating a general
identifier dictionary.

Fixes #744

Patch:
diff --git a/crates/typos-cli/src/dict.rs b/crates/typos-cli/src/dict.rs
index f69abe0..7f09952 100644
--- a/crates/typos-cli/src/dict.rs
+++ b/crates/typos-cli/src/dict.rs
@@ -20,9 +20,10 @@ impl BuiltIn {
 
     pub fn correct_ident<'s>(
         &'s self,
-        _ident: typos::tokens::Identifier<'_>,
+        ident_token: typos::tokens::Identifier<'_>,
     ) -> Option<Status<'s>> {
-        None
+        let ident = ident_token.token();
+        self.correct_ident_with_dict(ident)
     }
 
     pub fn correct_word<'s>(&'s self, word_token: typos::tokens::Word<'_>) -> Option<Status<'s>> {
@@ -32,7 +33,7 @@ impl BuiltIn {
 
         let word = word_token.token();
         let word_case = unicase::UniCase::new(word);
-        let mut corrections = if let Some(corrections) = self.correct_with_dict(word_case) {
+        let mut corrections = if let Some(corrections) = self.correct_word_with_dict(word_case) {
             if corrections.is_empty() {
                 Status::Invalid
             } else {
@@ -50,15 +51,32 @@ impl BuiltIn {
 
 #[cfg(feature = "dict")]
 impl BuiltIn {
+    fn correct_ident_with_dict<'s>(&self, ident: &str) -> Option<Status<'s>> {
+        match ident {
+            "O_WRONLY" => Some(Status::Valid),
+            _ => None,
+        }
+    }
+
     // Not using `Status` to avoid the allocations
-    fn correct_with_dict(&self, word: unicase::UniCase<&str>) -> Option<&'static [&'static str]> {
+    fn correct_word_with_dict(
+        &self,
+        word: unicase::UniCase<&str>,
+    ) -> Option<&'static [&'static str]> {
         typos_dict::WORD_TRIE.find(&word).copied()
     }
 }
 
 #[cfg(not(feature = "dict"))]
 impl BuiltIn {
-    fn correct_with_dict(&self, _word: unicase::UniCase<&str>) -> Option<&'static [&'static str]> {
+    fn correct_ident_with_dict<'s>(&self, _ident: &str) -> Option<Status<'s>> {
+        None
+    }
+
+    fn correct_word_with_dict(
+        &self,
+        _word: unicase::UniCase<&str>,
+    ) -> Option<&'static [&'static str]> {
         None
     }
 }
diff --git a/crates/typos-dict/src/lib.rs b/crates/typos-dict/src/lib.rs
index 4619424..808bec0 100644
--- a/crates/typos-dict/src/lib.rs
+++ b/crates/typos-dict/src/lib.rs
@@ -1,3 +1,3 @@
-mod dict_codegen;
+mod word_codegen;
 
-pub use crate::dict_codegen::*;
+pub use crate::word_codegen::WORD_TRIE;


Test patch:
diff --git a/crates/typos-cli/tests/cmd/false-positives.in/sample.py b/crates/typos-cli/tests/cmd/false-positives.in/sample.py
index dcf674d..692ff28 100644
--- a/crates/typos-cli/tests/cmd/false-positives.in/sample.py
+++ b/crates/typos-cli/tests/cmd/false-positives.in/sample.py
@@ -1,1 +1,5 @@
+import os
+
 from numpy.typing import NDArray  # should work
+
+print(os.O_WRONLY)  # should work
diff --git a/crates/typos-dict/src/dict_codegen.rs b/crates/typos-dict/src/word_codegen.rs
similarity index 100%
rename from crates/typos-dict/src/dict_codegen.rs
rename to crates/typos-dict/src/word_codegen.rs
diff --git a/crates/typos-dict/tests/codegen.rs b/crates/typos-dict/tests/codegen.rs
index e7c393a..fb6a317 100644
--- a/crates/typos-dict/tests/codegen.rs
+++ b/crates/typos-dict/tests/codegen.rs
@@ -1,16 +1,15 @@
-const DICT: &[u8] = include_bytes!("../assets/words.csv");
-
 #[test]
 fn codegen() {
     let mut content = vec![];
-    generate(&mut content);
+    const DICT: &[u8] = include_bytes!("../assets/words.csv");
+    generate(&mut content, "WORD", DICT);
 
     let content = String::from_utf8(content).unwrap();
     let content = codegenrs::rustfmt(&content, None).unwrap();
-    snapbox::assert_eq_path("./src/dict_codegen.rs", content);
+    snapbox::assert_eq_path("./src/word_codegen.rs", content);
 }
 
-fn generate<W: std::io::Write>(file: &mut W) {
+fn generate<W: std::io::Write>(file: &mut W, prefix: &str, dict: &[u8]) {
     writeln!(
         file,
         "// This file is @generated by {}",
@@ -23,13 +22,13 @@ fn generate<W: std::io::Write>(file: &mut W) {
     let records: Vec<_> = csv::ReaderBuilder::new()
         .has_headers(false)
         .flexible(true)
-        .from_reader(DICT)
+        .from_reader(dict)
         .records()
         .map(|r| r.unwrap())
         .collect();
     dictgen::generate_trie(
         file,
-        "WORD",
+        prefix,
         "&'static [&'static str]",
         records.iter().map(|record| {
             let mut record_fields = record.iter();