Skip to main content

clean_dev_dirs/config/
filter.rs

1//! Filtering configuration for project selection.
2//!
3//! This module defines the filtering options, project type filters, and sorting
4//! criteria used to determine which projects should be scanned, cleaned, and
5//! how they should be ordered in the output.
6
7use clap::ValueEnum;
8
9/// Enumeration of supported project type filters.
10///
11/// This enum is used to restrict scanning and cleaning to specific types of
12/// development projects.
13#[derive(Clone, Copy, PartialEq, Eq, Debug, ValueEnum, Default)]
14pub enum ProjectFilter {
15    /// Include all supported project types
16    #[default]
17    All,
18
19    /// Include only Rust projects (Cargo.toml + target/)
20    Rust,
21
22    /// Include only Node.js projects (package.json + `node_modules`/)
23    Node,
24
25    /// Include only Python projects (Python config files + cache dirs)
26    Python,
27
28    /// Include only Go projects (go.mod + vendor/)
29    Go,
30
31    /// Include only Java/Kotlin projects (pom.xml or build.gradle + target/ or build/)
32    Java,
33
34    /// Include only C/C++ projects (CMakeLists.txt or Makefile + build/)
35    Cpp,
36
37    /// Include only Swift projects (Package.swift + .build/)
38    Swift,
39
40    /// Include only .NET/C# projects (.csproj + bin/ + obj/)
41    #[value(name = "dotnet")]
42    DotNet,
43}
44
45/// Configuration for project filtering criteria.
46///
47/// This struct contains the filtering options used to determine which projects
48/// should be considered for cleanup based on size and modification time.
49#[derive(Clone)]
50pub struct FilterOptions {
51    /// Minimum size threshold for build directories
52    pub keep_size: String,
53
54    /// Minimum age in days for projects to be considered
55    pub keep_days: u32,
56}
57
58/// Enumeration of supported sorting criteria for project output.
59///
60/// This enum determines how projects are ordered in the output.
61/// Each variant has a natural default direction:
62/// - `Size`: largest first (descending)
63/// - `Age`: oldest first (ascending)
64/// - `Name`: alphabetical (ascending)
65/// - `Type`: grouped by type name alphabetically
66#[derive(Clone, Copy, PartialEq, Eq, Debug, ValueEnum)]
67pub enum SortCriteria {
68    /// Sort by build artifacts size (largest first by default)
69    Size,
70
71    /// Sort by build artifacts modification time (oldest first by default)
72    Age,
73
74    /// Sort by project name alphabetically (A-Z by default)
75    Name,
76
77    /// Sort by project type name alphabetically
78    Type,
79}
80
81/// Configuration for project sorting behavior.
82///
83/// Controls how the list of projects is ordered before display or processing.
84/// When `criteria` is `None`, projects are displayed in scan order.
85#[derive(Clone)]
86pub struct SortOptions {
87    /// The sorting criterion to apply, or `None` to preserve scan order
88    pub criteria: Option<SortCriteria>,
89
90    /// Whether to reverse the sort order
91    pub reverse: bool,
92}
93
94#[cfg(test)]
95mod tests {
96    use super::*;
97
98    #[test]
99    fn test_project_filter_equality() {
100        assert_eq!(ProjectFilter::All, ProjectFilter::All);
101        assert_eq!(ProjectFilter::Rust, ProjectFilter::Rust);
102        assert_eq!(ProjectFilter::Node, ProjectFilter::Node);
103        assert_eq!(ProjectFilter::Python, ProjectFilter::Python);
104        assert_eq!(ProjectFilter::Go, ProjectFilter::Go);
105        assert_eq!(ProjectFilter::Java, ProjectFilter::Java);
106        assert_eq!(ProjectFilter::Cpp, ProjectFilter::Cpp);
107        assert_eq!(ProjectFilter::Swift, ProjectFilter::Swift);
108        assert_eq!(ProjectFilter::DotNet, ProjectFilter::DotNet);
109
110        assert_ne!(ProjectFilter::All, ProjectFilter::Rust);
111        assert_ne!(ProjectFilter::Rust, ProjectFilter::Node);
112        assert_ne!(ProjectFilter::Node, ProjectFilter::Python);
113        assert_ne!(ProjectFilter::Python, ProjectFilter::Go);
114        assert_ne!(ProjectFilter::Go, ProjectFilter::Java);
115        assert_ne!(ProjectFilter::Java, ProjectFilter::Cpp);
116        assert_ne!(ProjectFilter::Cpp, ProjectFilter::Swift);
117        assert_ne!(ProjectFilter::Swift, ProjectFilter::DotNet);
118    }
119
120    #[test]
121    fn test_project_filter_copy() {
122        let original = ProjectFilter::Rust;
123        let copied = original;
124
125        assert_eq!(original, copied);
126    }
127
128    #[test]
129    fn test_project_filter_default() {
130        let default_filter = ProjectFilter::default();
131        assert_eq!(default_filter, ProjectFilter::All);
132    }
133
134    #[test]
135    fn test_filter_options_creation() {
136        let filter_opts = FilterOptions {
137            keep_size: "100MB".to_string(),
138            keep_days: 30,
139        };
140
141        assert_eq!(filter_opts.keep_size, "100MB");
142        assert_eq!(filter_opts.keep_days, 30);
143    }
144
145    #[test]
146    fn test_filter_options_clone() {
147        let original = FilterOptions {
148            keep_size: "100MB".to_string(),
149            keep_days: 30,
150        };
151        let cloned = original.clone();
152
153        assert_eq!(original.keep_size, cloned.keep_size);
154        assert_eq!(original.keep_days, cloned.keep_days);
155    }
156
157    #[test]
158    fn test_sort_criteria_equality() {
159        assert_eq!(SortCriteria::Size, SortCriteria::Size);
160        assert_eq!(SortCriteria::Age, SortCriteria::Age);
161        assert_eq!(SortCriteria::Name, SortCriteria::Name);
162        assert_eq!(SortCriteria::Type, SortCriteria::Type);
163
164        assert_ne!(SortCriteria::Size, SortCriteria::Age);
165        assert_ne!(SortCriteria::Name, SortCriteria::Type);
166    }
167
168    #[test]
169    fn test_sort_criteria_copy() {
170        let original = SortCriteria::Size;
171        let copied = original;
172        assert_eq!(original, copied);
173    }
174
175    #[test]
176    fn test_sort_options_creation() {
177        let sort_opts = SortOptions {
178            criteria: Some(SortCriteria::Size),
179            reverse: false,
180        };
181        assert_eq!(sort_opts.criteria, Some(SortCriteria::Size));
182        assert!(!sort_opts.reverse);
183    }
184
185    #[test]
186    fn test_sort_options_none_criteria() {
187        let sort_opts = SortOptions {
188            criteria: None,
189            reverse: false,
190        };
191        assert!(sort_opts.criteria.is_none());
192    }
193
194    #[test]
195    fn test_sort_options_clone() {
196        let original = SortOptions {
197            criteria: Some(SortCriteria::Age),
198            reverse: true,
199        };
200        let cloned = original.clone();
201
202        assert_eq!(original.criteria, cloned.criteria);
203        assert_eq!(original.reverse, cloned.reverse);
204    }
205}