Skip to main content

tailwind_rs_scanner/
lib.rs

1//! # tailwind-rs-scanner
2//!
3//! Advanced content scanning for Tailwind-RS Core, providing intelligent
4//! class detection and extraction from source files.
5//!
6//! This crate provides comprehensive content scanning capabilities:
7//! - Multi-language support (Rust, JavaScript, TypeScript, HTML, etc.)
8//! - Parallel file processing for performance
9//! - Intelligent class extraction with context awareness
10//! - File watching and incremental updates
11//! - Tree-sitter integration for accurate parsing
12//!
13//! ## Features
14//!
15//! - **Multi-Language Support**: Rust, JS/TS, HTML, Vue, Svelte, and more
16//! - **Parallel Processing**: Multi-threaded file scanning for speed
17//! - **Intelligent Extraction**: Context-aware class detection
18//! - **File Watching**: Real-time file change detection
19//! - **Tree-sitter Integration**: Accurate AST-based parsing
20//! - **Performance**: Optimized for large codebases
21//!
22//! ## Example
23//!
24//! ```rust
25//! use tailwind_rs_scanner::*;
26//!
27//! #[tokio::main]
28//! async fn main() -> Result<(), ScannerError> {
29//!     let scanner = ContentScanner::new(ScanConfig::default())?;
30//!     
31//!     let classes = scanner.scan_for_classes().await?;
32//!     println!("Found {} classes", classes.total_classes());
33//!     
34//!     // Watch for changes
35//!     let mut watcher = scanner.watch().await?;
36//!     while let Some(update) = watcher.next().await {
37//!         println!("Classes updated: {:?}", update);
38//!     }
39//!     
40//!     Ok(())
41//! }
42//! ```
43
44pub mod cache;
45pub mod class_extractor;
46pub mod content_config;
47pub mod error;
48pub mod file_scanner;
49pub mod file_watcher;
50pub mod glob_matcher;
51pub mod parallel_processor;
52pub mod tree_sitter_parser;
53
54// Re-export main types
55pub use cache::{CacheEntry, CacheStats, ScanCache};
56pub use class_extractor::{ClassContext, ClassExtractor, ExtractedClass};
57pub use content_config::{ContentConfig, FilePattern, ScanConfig};
58pub use error::{Result, ScannerError};
59pub use file_scanner::{ClassSet, ContentScanner, FileInfo, FileScanner, FileType};
60pub use file_watcher::{FileWatcher, WatchConfig, WatchEvent};
61pub use glob_matcher::{GlobMatcher, GlobPattern};
62pub use parallel_processor::{ParallelProcessor, ProcessingStats};
63pub use tree_sitter_parser::{LanguageSupport, ParseResult, TreeSitterParser};
64
65/// Version information
66pub const VERSION: &str = env!("CARGO_PKG_VERSION");
67
68/// Default configuration for content scanning
69pub fn default_config() -> ScanConfig {
70    ScanConfig::default()
71}
72
73/// Create a new content scanner with default configuration
74pub fn new_scanner() -> Result<ContentScanner> {
75    ContentScanner::new(ScanConfig::default())
76}
77
78/// Scan content for classes using default configuration
79pub async fn scan_content(paths: &[String]) -> Result<ClassSet> {
80    let scanner = new_scanner()?;
81    scanner.scan_paths(paths).await
82}
83
84#[cfg(test)]
85mod tests {
86    use super::*;
87
88    #[test]
89    fn test_version_constant() {
90        assert!(!VERSION.is_empty());
91        assert!(VERSION.chars().any(|c| c.is_ascii_digit()));
92    }
93
94    #[test]
95    fn test_default_config() {
96        let config = default_config();
97        assert!(!config.content_config.patterns.is_empty());
98        assert!(config.parallel_processing);
99    }
100
101    #[tokio::test]
102    async fn test_scan_content() {
103        let paths = vec!["test.html".to_string()];
104        let result = scan_content(&paths).await;
105        // This will fail if the file doesn't exist, which is expected
106        assert!(result.is_err() || result.is_ok());
107    }
108}