Repository: TabbyML/tabby
File: ee/tabby-webserver/src/service/answer.rs (Rust)

Code before:
        if file_hits.len() > 1 {
            // construct the full path to the file
            let path: PathBuf = repository.dir.join(&file_hits[0].doc.filepath);
            let all_lines = match read_file_content(&path) {
                Ok(lines) => lines,
                Err(e) => {
                    warn!("Error reading file {}: {}", path.display(), e);
                    //cannot read the file, just extend the hits
                    result.extend(file_hits);
                    continue;
                }
            };

            if !all_lines.is_empty() {
                let mut insert_hit = file_hits[0].clone();
                insert_hit.scores =
                    file_hits
                        .iter()
                        .fold(CodeSearchScores::default(), |mut acc, hit| {
                            acc.bm25 += hit.scores.bm25;
                            acc.embedding += hit.scores.embedding;
                            acc.rrf += hit.scores.rrf;
                            acc
                        });
                // average the scores
                let len = file_hits.len() as f32;
                insert_hit.scores.bm25 /= len;
                insert_hit.scores.embedding /= len;
                insert_hit.scores.rrf /= len;
                insert_hit.doc.body = all_lines.join("\n");
                result.push(insert_hit);
            }
        } else {
            result.extend(file_hits);
        }
    }
    result
}

#[derive(Debug)]
// Error for when the file is too large
struct FileTooLargeError;

impl fmt::Display for FileTooLargeError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "File is too large (more than 200 lines)")
    }
}

impl Error for FileTooLargeError {}


Review comment (suggestion):
```suggestion
                let num_files = file_hits.len() as f32;
```

Code after:

    let mut result = Vec::with_capacity(file_hits.len());

    for (_, file_hits) in file_hits {
        if file_hits.len() > 1 {
            // construct the full path to the file
            let path: PathBuf = repository.dir.join(&file_hits[0].doc.filepath);
            let file_content = match read_file_content(&path) {
                Some(lines) => lines,
                None => {
                    //cannot read the file, just extend the hits
                    result.extend(file_hits);
                    continue;
                }
            };

            if !file_content.is_empty() {
                let mut insert_hit = file_hits[0].clone();
                insert_hit.scores =
                    file_hits
                        .iter()
                        .fold(CodeSearchScores::default(), |mut acc, hit| {
                            acc.bm25 += hit.scores.bm25;
                            acc.embedding += hit.scores.embedding;
                            acc.rrf += hit.scores.rrf;
                            acc
                        });
                // average the scores
                let num_files = file_hits.len() as f32;
                insert_hit.scores.bm25 /= num_files;
                insert_hit.scores.embedding /= num_files;
                insert_hit.scores.rrf /= num_files;
                insert_hit.doc.body = file_content;
                result.push(insert_hit);
            }
        } else {
            result.extend(file_hits);
        }
    }
    result
}

/// Read file content and return raw file content string, it will return nothing if the file is over 200 lines
pub fn read_file_content(path: &Path) -> Option<String> {
    if count_lines(path).ok()? > 200 {
        return None;
    }

    let mut file = match File::open(path) {
        Ok(file) => file,
        Err(e) => {