1use std::path::PathBuf;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
7pub enum Profile {
8 Fast,
10 #[default]
12 Full,
13 Deep,
15}
16
17impl std::str::FromStr for Profile {
18 type Err = String;
19 fn from_str(s: &str) -> Result<Self, Self::Err> {
20 match s.to_lowercase().as_str() {
21 "fast" => Ok(Profile::Fast),
22 "full" => Ok(Profile::Full),
23 "deep" => Ok(Profile::Deep),
24 _ => Err(format!("unknown profile: {}", s)),
25 }
26 }
27}
28
29#[derive(Debug, Clone, Copy, PartialEq, Eq)]
31pub enum CollectorName {
32 Fmt,
33 Clippy,
34 Tests,
35 Coverage,
36 Deny,
37 Audit,
38 Hack,
39 Mutants,
40 Duplicates,
41 Loc,
42 Size,
43 Complexity,
44}
45
46impl std::fmt::Display for CollectorName {
47 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
48 match self {
49 CollectorName::Fmt => write!(f, "fmt"),
50 CollectorName::Clippy => write!(f, "clippy"),
51 CollectorName::Tests => write!(f, "tests"),
52 CollectorName::Coverage => write!(f, "coverage"),
53 CollectorName::Deny => write!(f, "deny"),
54 CollectorName::Audit => write!(f, "audit"),
55 CollectorName::Hack => write!(f, "hack"),
56 CollectorName::Mutants => write!(f, "mutants"),
57 CollectorName::Duplicates => write!(f, "duplicates"),
58 CollectorName::Loc => write!(f, "loc"),
59 CollectorName::Size => write!(f, "size"),
60 CollectorName::Complexity => write!(f, "complexity"),
61 }
62 }
63}
64
65impl std::str::FromStr for CollectorName {
66 type Err = String;
67 fn from_str(s: &str) -> Result<Self, Self::Err> {
68 match s.to_lowercase().as_str() {
69 "fmt" => Ok(CollectorName::Fmt),
70 "clippy" => Ok(CollectorName::Clippy),
71 "tests" => Ok(CollectorName::Tests),
72 "coverage" => Ok(CollectorName::Coverage),
73 "deny" => Ok(CollectorName::Deny),
74 "audit" => Ok(CollectorName::Audit),
75 "hack" => Ok(CollectorName::Hack),
76 "mutants" => Ok(CollectorName::Mutants),
77 "duplicates" => Ok(CollectorName::Duplicates),
78 "loc" => Ok(CollectorName::Loc),
79 "size" => Ok(CollectorName::Size),
80 "complexity" => Ok(CollectorName::Complexity),
81 _ => Err(format!("unknown collector: {}", s)),
82 }
83 }
84}
85
86#[derive(Debug, Clone)]
88pub struct Context {
89 pub workspace_root: PathBuf,
91 pub profile: Profile,
93 pub disabled_collectors: Vec<CollectorName>,
95 pub output_dir: PathBuf,
97}
98
99impl Context {
100 pub fn new(workspace_root: PathBuf) -> Self {
101 Self {
102 workspace_root,
103 profile: Profile::default(),
104 disabled_collectors: Vec::new(),
105 output_dir: PathBuf::from("quality"),
106 }
107 }
108
109 pub fn with_profile(mut self, profile: Profile) -> Self {
110 self.profile = profile;
111 self
112 }
113
114 pub fn with_output_dir(mut self, dir: PathBuf) -> Self {
115 self.output_dir = dir;
116 self
117 }
118
119 pub fn disable_collector(&mut self, name: CollectorName) {
120 self.disabled_collectors.push(name);
121 }
122
123 pub fn is_collector_disabled(&self, name: CollectorName) -> bool {
124 self.disabled_collectors.contains(&name)
125 }
126}
127
128#[cfg(test)]
129mod tests {
130 use super::*;
131
132 #[test]
133 fn test_profile_parsing() {
134 assert_eq!("fast".parse::<Profile>().unwrap(), Profile::Fast);
135 assert_eq!("FULL".parse::<Profile>().unwrap(), Profile::Full);
136 assert_eq!("Deep".parse::<Profile>().unwrap(), Profile::Deep);
137 assert!("unknown".parse::<Profile>().is_err());
138 }
139
140 #[test]
141 fn test_context_disabled_collectors() {
142 let mut ctx = Context::new(PathBuf::from("/tmp"));
143 assert!(!ctx.is_collector_disabled(CollectorName::Clippy));
144 ctx.disable_collector(CollectorName::Clippy);
145 assert!(ctx.is_collector_disabled(CollectorName::Clippy));
146 assert!(!ctx.is_collector_disabled(CollectorName::Tests));
147 }
148}