archunit/common/fluentapi/
check_options.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
use crate::common::LoggingOptions;

/// Options that control how one terminal architecture check runs.
///
/// The default is deliberately defensive and quiet: empty selections fail, logging is disabled,
/// an existing graph cache may be reused, and test-only source targets are excluded. Builders
/// consume and return the bag so a configured value can be cloned and branched without mutation.
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub struct CheckOptions {
    allow_empty_tests: bool,
    logging: Option<LoggingOptions>,
    clear_cache: bool,
    include_test_sources: bool,
}

impl CheckOptions {
    /// Creates the ordinary strict, quiet check configuration.
    #[must_use]
    pub const fn new() -> Self {
        Self {
            allow_empty_tests: false,
            logging: None,
            clear_cache: false,
            include_test_sources: false,
        }
    }

    /// Returns whether a selector that matches nothing may pass.
    #[must_use]
    pub const fn allows_empty_tests(&self) -> bool {
        self.allow_empty_tests
    }

    /// Controls whether a selector that matches nothing may pass.
    #[must_use]
    pub const fn with_allow_empty_tests(mut self, allow: bool) -> Self {
        self.allow_empty_tests = allow;
        self
    }

    /// Returns this check's logging configuration, or `None` when it is quiet.
    #[must_use]
    pub const fn logging(&self) -> Option<&LoggingOptions> {
        self.logging.as_ref()
    }

    /// Enables per-check logging with the supplied configuration.
    #[must_use]
    pub fn with_logging(mut self, logging: LoggingOptions) -> Self {
        self.logging = Some(logging);
        self
    }

    /// Returns whether the shared extraction cache must be cleared before this check.
    #[must_use]
    pub const fn clears_cache(&self) -> bool {
        self.clear_cache
    }

    /// Controls whether extraction starts from an empty graph cache.
    #[must_use]
    pub const fn with_clear_cache(mut self, clear: bool) -> Self {
        self.clear_cache = clear;
        self
    }

    /// Returns whether Cargo test, example, and benchmark targets participate in analysis.
    #[must_use]
    pub const fn includes_test_sources(&self) -> bool {
        self.include_test_sources
    }

    /// Controls whether Cargo test, example, and benchmark targets participate in analysis.
    #[must_use]
    pub const fn with_test_sources(mut self, include: bool) -> Self {
        self.include_test_sources = include;
        self
    }
}

impl Default for CheckOptions {
    fn default() -> Self {
        Self::new()
    }
}

#[cfg(test)]
mod tests {
    use super::CheckOptions;
    use crate::common::LoggingOptions;

    #[test]
    fn defaults_are_strict_quiet_cached_and_production_only() {
        let options = CheckOptions::default();

        assert!(!options.allows_empty_tests());
        assert!(options.logging().is_none());
        assert!(!options.clears_cache());
        assert!(!options.includes_test_sources());
    }

    #[test]
    fn consuming_builders_compose_every_current_option() {
        let options = CheckOptions::new()
            .with_allow_empty_tests(true)
            .with_logging(LoggingOptions::new())
            .with_clear_cache(true)
            .with_test_sources(true);

        assert!(options.allows_empty_tests());
        assert!(options.logging().is_some());
        assert!(options.clears_cache());
        assert!(options.includes_test_sources());
    }

    #[test]
    fn configured_bags_can_be_branched_without_mutating_the_base() {
        let base = CheckOptions::new().with_clear_cache(true);
        let derived = base.clone().with_allow_empty_tests(true);

        assert!(!base.allows_empty_tests());
        assert!(base.clears_cache());
        assert!(derived.allows_empty_tests());
        assert!(derived.clears_cache());
    }
}