Skip to main content

redact_core/recognizers/
mod.rs

1// Copyright (c) 2026 Censgate LLC.
2// Licensed under the Business Source License 1.1 (BUSL-1.1).
3// See the LICENSE file in the project root for license details,
4// including the Additional Use Grant, Change Date, and Change License.
5
6pub mod pattern;
7pub mod registry;
8
9pub use registry::RecognizerRegistry;
10
11use crate::types::{EntityType, RecognizerResult};
12use anyhow::Result;
13use std::fmt::Debug;
14
15/// Trait for all PII recognizers
16pub trait Recognizer: Send + Sync + Debug {
17    /// Get the name of this recognizer
18    fn name(&self) -> &str;
19
20    /// Get the entity types this recognizer can detect
21    fn supported_entities(&self) -> &[EntityType];
22
23    /// Analyze text and return detected entities
24    fn analyze(&self, text: &str, language: &str) -> Result<Vec<RecognizerResult>>;
25
26    /// Get the minimum confidence score for this recognizer
27    fn min_score(&self) -> f32 {
28        0.0
29    }
30
31    /// Check if this recognizer supports the given language
32    fn supports_language(&self, language: &str) -> bool {
33        language == "en" // Default to English only
34    }
35}
36
37/// Trait for recognizers that can be loaded from configuration
38pub trait ConfigurableRecognizer: Recognizer {
39    /// Configuration type for this recognizer
40    type Config;
41
42    /// Create a new instance from configuration
43    fn from_config(config: Self::Config) -> Result<Self>
44    where
45        Self: Sized;
46}
47
48#[cfg(test)]
49mod tests {
50    use super::*;
51
52    #[derive(Debug)]
53    struct TestRecognizer;
54
55    impl Recognizer for TestRecognizer {
56        fn name(&self) -> &str {
57            "test"
58        }
59
60        fn supported_entities(&self) -> &[EntityType] {
61            &[EntityType::Person]
62        }
63
64        fn analyze(&self, _text: &str, _language: &str) -> Result<Vec<RecognizerResult>> {
65            Ok(vec![])
66        }
67    }
68
69    #[test]
70    fn test_recognizer_trait() {
71        let recognizer = TestRecognizer;
72        assert_eq!(recognizer.name(), "test");
73        assert_eq!(recognizer.supported_entities(), &[EntityType::Person]);
74        assert!(recognizer.supports_language("en"));
75        assert!(!recognizer.supports_language("es"));
76    }
77}