use std::path::Path;
use sha2::{Digest, Sha256};
pub fn read_source_file(path: &Path) -> std::io::Result<String> {
let bytes = std::fs::read(path)?;
if bytes.starts_with(&[0xFF, 0xFE]) {
let u16s: Vec<u16> = bytes[2..]
.chunks_exact(2)
.map(|pair| u16::from_le_bytes([pair[0], pair[1]]))
.collect();
return String::from_utf16(&u16s)
.map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e));
}
if bytes.starts_with(&[0xFE, 0xFF]) {
let u16s: Vec<u16> = bytes[2..]
.chunks_exact(2)
.map(|pair| u16::from_be_bytes([pair[0], pair[1]]))
.collect();
return String::from_utf16(&u16s)
.map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e));
}
let start = if bytes.starts_with(&[0xEF, 0xBB, 0xBF]) {
3
} else {
0
};
String::from_utf8(bytes[start..].to_vec())
.map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))
}
pub fn file_stat(path: &Path) -> Option<(i64, u64)> {
let meta = std::fs::metadata(path).ok()?;
let mtime = meta.modified().ok()?;
let secs = mtime.duration_since(std::time::UNIX_EPOCH).ok()?.as_secs() as i64;
Some((secs, meta.len()))
}
pub fn content_hash(content: &str) -> String {
let mut hasher = Sha256::new();
hasher.update(content.as_bytes());
let result = hasher.finalize();
hex::encode(result)
}