Rest/Fn/SWC/Watch/
Compile.rs

1#[tracing::instrument(skip(Option))]
2pub async fn Fn(Option:super::Option) -> anyhow::Result<()> {
3	let (Allow, mut Mark) = mpsc::unbounded_channel();
4	let Queue = FuturesUnordered::new();
5	let Compiler = Arc::new(crate::Struct::SWC::Compiler::new(Option.config.clone()));
6
7	for file in Option
8		.entry
9		.into_par_iter()
10		.filter_map(|entry| {
11			entry
12				.last()
13				.filter(|last| last.ends_with(&Option.pattern))
14				.map(|_| entry[0..entry.len() - 1].join(&Option.separator.to_string()))
15		})
16		.collect::<Vec<String>>()
17	{
18		let Allow = Allow.clone();
19		let Compiler = Arc::clone(&Compiler);
20
21		Queue.push(tokio::spawn(async move {
22			match tokio::fs::read_to_string(&file).await {
23				Ok(input) => {
24					// Use spawn_blocking for CPU-intensive compilation
25					let file_clone = file.clone();
26					let result = tokio::task::spawn_blocking(move || Compiler.compile_file(&file_clone, input)).await;
27
28					match result {
29						Ok(inner_result) => {
30							match inner_result {
31								Ok(output) => {
32									if let Err(e) = Allow.send((file.clone(), Ok(output))) {
33										error!("Cannot send compilation result: {}", e);
34									}
35								},
36								Err(e) => {
37									error!("Compilation error for {}: {}", file, e);
38									if let Err(e) = Allow.send((file.clone(), Err(e))) {
39										error!("Cannot send compilation error: {}", e);
40									}
41								},
42							}
43						},
44						Err(join_err) => {
45							error!("Task join error for {}: {}", file, join_err);
46							if let Err(e) = Allow.send((file.clone(), Err(anyhow::anyhow!(join_err)))) {
47								error!("Cannot send join error: {}", e);
48							}
49						},
50					}
51				},
52				Err(e) => {
53					error!("Failed to read file {}: {}", file, e);
54					if let Err(e) = Allow.send((file.clone(), Err(anyhow::anyhow!(e)))) {
55						error!("Cannot send file read error: {}", e);
56					}
57				},
58			}
59		}));
60	}
61
62	tokio::spawn(async move {
63		Queue.collect::<Vec<_>>().await;
64		drop(Allow);
65	});
66
67	let mut Count = 0;
68	let mut Error = 0;
69
70	while let Some((file, result)) = Mark.recv().await {
71		match result {
72			Ok(output) => {
73				info!("Compiled: {} -> {}", file, output);
74				Count += 1;
75			},
76			Err(e) => {
77				warn!("Failed to compile {}: {}", file, e);
78				Error += 1;
79			},
80		}
81	}
82
83	let Outlook = Compiler.Outlook.lock().unwrap();
84
85	info!(
86		"Compilation complete. Processed {} files in {:?}. {} successful, {} failed.",
87		Outlook.Count, Outlook.Elapsed, Count, Error
88	);
89
90	Ok(())
91}
92
93use std::sync::Arc;
94
95use futures::stream::{FuturesUnordered, StreamExt};
96use rayon::prelude::{IntoParallelIterator, ParallelIterator};
97use tokio::sync::mpsc;
98use tracing::{error, info, warn};