tailwind_rs_postcss/
source_map.rs

1//! Source map generation for PostCSS integration
2//!
3//! This module provides source map generation capabilities.
4
5use crate::error::Result;
6use serde::{Deserialize, Serialize};
7
8/// Source map generator
9#[derive(Debug)]
10pub struct SourceMapGenerator;
11
12/// Source map representation
13#[derive(Debug, Clone, Serialize, Deserialize)]
14pub struct SourceMap {
15    pub version: u32,
16    pub sources: Vec<String>,
17    pub names: Vec<String>,
18    pub mappings: String,
19    pub file: Option<String>,
20    pub source_root: Option<String>,
21    pub sources_content: Option<Vec<String>>,
22}
23
24/// Source map options
25#[derive(Debug, Clone)]
26pub struct SourceMapOptions {
27    pub inline: bool,
28    pub file: Option<String>,
29    pub source_root: Option<String>,
30    pub sources_content: bool,
31}
32
33impl SourceMapGenerator {
34    /// Create a new source map generator
35    pub fn new() -> Self {
36        Self
37    }
38    
39    /// Generate source map
40    pub fn generate(
41        &self,
42        input: &str,
43        output: &str,
44        options: &SourceMapOptions,
45    ) -> Result<SourceMap> {
46        // Generate a basic source map
47        let sources = if options.sources_content {
48            vec![input.to_string()]
49        } else {
50            vec![]
51        };
52        
53        let sources_content = if options.sources_content {
54            Some(vec![input.to_string()])
55        } else {
56            None
57        };
58        
59        // Generate basic mappings (1:1 mapping for now)
60        let mappings = self.generate_mappings(input, output);
61        
62        Ok(SourceMap {
63            version: 3,
64            sources,
65            names: Vec::new(),
66            mappings,
67            file: options.file.clone(),
68            source_root: options.source_root.clone(),
69            sources_content,
70        })
71    }
72    
73    /// Generate basic source map mappings
74    fn generate_mappings(&self, input: &str, output: &str) -> String {
75        // For now, generate a simple 1:1 mapping
76        // In a real implementation, this would track the actual transformations
77        let input_lines = input.lines().count();
78        let output_lines = output.lines().count();
79        
80        if input_lines == output_lines {
81            // Simple 1:1 mapping
82            format!("AAAA;{}", input_lines)
83        } else {
84            // More complex mapping would be needed
85            "AAAA".to_string()
86        }
87    }
88}
89
90#[cfg(test)]
91mod tests {
92    use super::*;
93
94    #[test]
95    fn test_source_map_generator() {
96        let generator = SourceMapGenerator::new();
97        let options = SourceMapOptions {
98            inline: false,
99            file: None,
100            source_root: None,
101            sources_content: true,
102        };
103        
104        let result = generator.generate("input", "output", &options);
105        assert!(result.is_ok());
106    }
107}