data_privacy/common_taxonomy/
mod.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! A simple data taxonomy with universal data classes.
5//!
6//! Data classes in this taxonomy are generic in nature and are useful in a few situations:
7//!
8//! * [`Insensitive`] is used when data is specifically not classified.
9//! * [`UnknownSensitivity`] is used when data is sensitive, but the specific
10//!   classification is unknown.
11//! * [`Sensitive`] is primarily intended for libraries to indicate particular
12//!   data contains some form of sensitive information. General-purpose libraries
13//!   are usually agnostic to the application's specific data taxonomy, so if they
14//!   need to classify data, they can use [Sensitive] as a general indication to
15//!   the application that the data is sensitive.
16
17use data_privacy_macros::taxonomy;
18
19/// A simple data taxonomy with universal data classes.
20#[cfg_attr(feature = "serde", taxonomy(common, serde = true))]
21#[cfg_attr(not(feature = "serde"), taxonomy(common, serde = false))]
22#[derive(Debug, Clone, Eq, PartialEq, Hash)]
23#[non_exhaustive]
24pub enum CommonTaxonomy {
25    /// The `sensitive` data class indicates data must be treated carefully.
26    ///
27    /// This data class is typically used in libraries which are agnostic to a
28    /// specific data taxonomy.
29    Sensitive,
30
31    /// The `insensitive` data class indicates data is specifically not classified.
32    Insensitive,
33
34    /// The `unknown_sensitivity` data class indicates data has an unknown classification.
35    UnknownSensitivity,
36}
37
38#[cfg(test)]
39mod tests {
40    use super::*;
41    use crate::DataClass;
42
43    #[test]
44    fn test_common_taxonomy() {
45        assert_eq!(CommonTaxonomy::Sensitive.data_class(), DataClass::new("common", "sensitive"));
46        assert_eq!(CommonTaxonomy::Insensitive.data_class(), DataClass::new("common", "insensitive"));
47        assert_eq!(
48            CommonTaxonomy::UnknownSensitivity.data_class(),
49            DataClass::new("common", "unknown_sensitivity")
50        );
51    }
52
53    #[test]
54    fn test_debug_trait() {
55        assert_eq!(format!("{:?}", Sensitive::new(2)), "<common/sensitive:REDACTED>");
56        assert_eq!(format!("{:?}", Insensitive::new("Hello")), "<common/insensitive:REDACTED>");
57        assert_eq!(
58            format!("{:?}", UnknownSensitivity::new(31.4)),
59            "<common/unknown_sensitivity:REDACTED>"
60        );
61    }
62
63    #[test]
64    fn test_partial_eq() {
65        assert_eq!(CommonTaxonomy::Sensitive, CommonTaxonomy::Sensitive.data_class());
66        assert_eq!(CommonTaxonomy::Insensitive, CommonTaxonomy::Insensitive.data_class());
67        assert_eq!(CommonTaxonomy::UnknownSensitivity, CommonTaxonomy::UnknownSensitivity.data_class());
68        assert_ne!(CommonTaxonomy::Sensitive, CommonTaxonomy::Insensitive.data_class());
69
70        // Ensure that the equality is symmetric
71        assert_eq!(CommonTaxonomy::Sensitive.data_class(), CommonTaxonomy::Sensitive,);
72        assert_ne!(CommonTaxonomy::Sensitive.data_class(), CommonTaxonomy::Insensitive);
73    }
74
75    #[test]
76    fn test_mapping() {
77        let sensitive_int = Sensitive::new(42);
78        let sensitive_str = sensitive_int.map(|i| format!("The answer is {i}"));
79        assert_eq!(sensitive_str.declassify(), "The answer is 42");
80    }
81}