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 || {
27						Compiler.compile_file(&file_clone, input)
28					}).await;
29
30					match result {
31						Ok(inner_result) => match inner_result {
32							Ok(output) => {
33								if let Err(e) = Allow.send((file.clone(), Ok(output))) {
34									error!("Cannot send compilation result: {}", e);
35								}
36							},
37							Err(e) => {
38								error!("Compilation error for {}: {}", file, e);
39								if let Err(e) = Allow.send((file.clone(), Err(e))) {
40									error!("Cannot send compilation error: {}", e);
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;
94use futures::stream::{FuturesUnordered, StreamExt};
95use rayon::prelude::{IntoParallelIterator, ParallelIterator};
96use tokio::sync::mpsc;
97use tracing::{error, info, warn};