Skip to main content

join_ai/
processor.rs

1use std::fs::{self, File};
2use std::io::{self, Write};
3use std::path::PathBuf;
4use std::sync::mpsc;
5
6/// This module handles the processing of files. It receives file paths from the
7/// walker, reads their content, and writes it to the final output file.
8///
9/// # Arguments
10/// * `rx` - The receiver end of a channel, which provides `PathBuf`s from the walker.
11/// * `output_file_path` - The path to the file where content should be written.
12pub fn process_files(
13    rx: mpsc::Receiver<PathBuf>,
14    output_file_path: &PathBuf,
15) -> anyhow::Result<()> {
16    // Create or truncate the output file, making it ready for writing.
17    let mut output_file = File::create(output_file_path)?;
18
19    // Iterate over every file path sent by the walker.
20    // This loop will block until the channel is empty and the sender is dropped.
21    for path in rx {
22        match fs::read(&path) {
23            Ok(contents) => {
24                // A simple and robust way to detect binary files is to check for the NUL byte,
25                // which is common in compiled files but rare in text files.
26                if contents.contains(&0) {
27                    println!("Skipping binary file: {}", path.display());
28                    continue; // Skip to the next file.
29                }
30
31                // Write a header comment to delineate files in the concatenated output.
32                writeln!(output_file, "// FILE: {}", path.display())?;
33                // Write the actual content of the file.
34                output_file.write_all(&contents)?;
35                // Add a newline for spacing between files.
36                writeln!(output_file)?;
37            }
38            Err(e) => {
39                // It's possible to encounter files that can't be read (e.g., system pipes,
40                // broken symlinks). We log these errors but don't stop the process.
41                if e.kind() != io::ErrorKind::InvalidData {
42                    eprintln!("Failed to read file {}: {}", path.display(), e);
43                }
44            }
45        }
46    }
47
48    Ok(())
49}