tailwind_rs_postcss/purger/
mod.rs

1//! CSS Purging System
2//!
3//! This module provides comprehensive CSS purging functionality for removing
4//! unused CSS classes, essential for Tailwind CSS production builds.
5
6pub mod class_extractor;
7pub mod content_scanner;
8pub mod rule_filter;
9pub mod types;
10
11use types::*;
12
13/// Main CSS purger for removing unused CSS classes
14pub struct CSSPurger {
15    content_scanner: content_scanner::ContentScanner,
16    class_extractor: class_extractor::ClassExtractor,
17    rule_filter: rule_filter::RuleFilter,
18    config: PurgeConfig,
19}
20
21impl CSSPurger {
22    /// Create a new CSS purger with default configuration
23    pub fn new() -> Self {
24        Self::with_config(PurgeConfig::default())
25    }
26
27    /// Create a new CSS purger with custom configuration
28    pub fn with_config(config: PurgeConfig) -> Self {
29        Self {
30            content_scanner: content_scanner::ContentScanner::new(),
31            class_extractor: class_extractor::ClassExtractor::new(),
32            rule_filter: rule_filter::RuleFilter::new(),
33            config,
34        }
35    }
36
37    /// Purge unused CSS from content
38    pub fn purge(
39        &mut self,
40        css: &str,
41        content_paths: &[String],
42    ) -> Result<PurgeResult, PurgeError> {
43        let start_time = std::time::Instant::now();
44
45        // Step 1: Scan content for used classes
46        let used_classes = self.content_scanner.scan_content(content_paths)?;
47
48        // Step 2: Extract CSS classes from CSS
49        let css_classes = self.class_extractor.extract_classes(css)?;
50
51        // Step 3: Filter CSS rules based on used classes
52        let filtered_css = self
53            .rule_filter
54            .filter_rules(css, &used_classes, &self.config)?;
55
56        let processing_time = start_time.elapsed();
57        let original_size = css.len();
58        let purged_size = filtered_css.len();
59        let size_reduction = if original_size > 0 {
60            ((original_size - purged_size) as f64 / original_size as f64) * 100.0
61        } else {
62            0.0
63        };
64
65        Ok(PurgeResult {
66            purged_css: filtered_css,
67            used_classes: used_classes.len(),
68            removed_classes: css_classes.len() - used_classes.len(),
69            original_size,
70            purged_size,
71            size_reduction_percentage: size_reduction,
72            processing_time,
73        })
74    }
75
76    /// Purge with advanced options
77    pub fn purge_advanced(
78        &mut self,
79        css: &str,
80        content_paths: &[String],
81        options: &PurgeOptions,
82    ) -> Result<PurgeResult, PurgeError> {
83        let start_time = std::time::Instant::now();
84
85        // Step 1: Scan content for used classes with advanced options
86        let used_classes = self
87            .content_scanner
88            .scan_content_advanced(content_paths, options)?;
89
90        // Step 2: Extract CSS classes from CSS
91        let css_classes = self.class_extractor.extract_classes(css)?;
92
93        // Step 3: Filter CSS rules based on used classes with advanced options
94        let filtered_css =
95            self.rule_filter
96                .filter_rules_advanced(css, &used_classes, &self.config, options)?;
97
98        let processing_time = start_time.elapsed();
99        let original_size = css.len();
100        let purged_size = filtered_css.len();
101        let size_reduction = if original_size > 0 {
102            ((original_size - purged_size) as f64 / original_size as f64) * 100.0
103        } else {
104            0.0
105        };
106
107        Ok(PurgeResult {
108            purged_css: filtered_css,
109            used_classes: used_classes.len(),
110            removed_classes: css_classes.len() - used_classes.len(),
111            original_size,
112            purged_size,
113            size_reduction_percentage: size_reduction,
114            processing_time,
115        })
116    }
117
118    /// Get purge statistics
119    pub fn get_statistics(&self) -> PurgeStatistics {
120        PurgeStatistics {
121            total_purges: 0, // Will be updated during purging
122            average_size_reduction: 0.0,
123            processing_time: std::time::Duration::from_secs(0),
124        }
125    }
126}
127
128// Re-export types for convenience
129pub use types::*;