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}