kataglyphis_rustprojecttemplate/
utils.rs

1// src/utils.rs
2use std::path::Path;
3
4use anyhow::{Context, Result};
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7pub struct FileStats {
8    pub lines: usize,
9    pub words: usize,
10    pub bytes: u64,
11}
12
13/// Platform-agnostic read_file shim. Prefer using `crate::platform::read_file`
14/// for platform-specific implementations; this remains as a compatibility
15/// shim that delegates to the platform module.
16pub async fn read_file(path: impl AsRef<Path>) -> Result<String> {
17    crate::platform::read_file(path).await
18}
19
20fn count_lines_and_words(path: &Path) -> Result<(usize, usize)> {
21    use std::io::{BufRead, BufReader};
22    let file = std::fs::File::open(path)
23        .with_context(|| format!("Failed to open file '{}'", path.display()))?;
24    let reader = BufReader::new(file);
25    let mut lines = 0usize;
26    let mut words = 0usize;
27    for line in reader.lines() {
28        let line =
29            line.with_context(|| format!("Failed to read line from '{}'", path.display()))?;
30        lines += 1;
31        words += line.split_whitespace().count();
32    }
33    Ok((lines, words))
34}
35
36pub async fn file_stats(path: impl AsRef<Path>) -> Result<FileStats> {
37    let path = path.as_ref();
38
39    #[cfg(not(target_arch = "wasm32"))]
40    let bytes = tokio::fs::metadata(path)
41        .await
42        .with_context(|| format!("Failed to read metadata for '{}'", path.display()))?
43        .len();
44
45    #[cfg(target_arch = "wasm32")]
46    let bytes = std::fs::metadata(path)
47        .with_context(|| format!("Failed to read metadata for '{}'", path.display()))?
48        .len();
49
50    let path_owned = path.to_path_buf();
51
52    #[cfg(not(target_arch = "wasm32"))]
53    let (lines, words) = tokio::task::spawn_blocking(move || count_lines_and_words(&path_owned))
54        .await
55        .context("Blocking task panicked")??;
56
57    #[cfg(target_arch = "wasm32")]
58    let (lines, words) = count_lines_and_words(&path_owned)?;
59
60    Ok(FileStats {
61        lines,
62        words,
63        bytes,
64    })
65}