#![allow(dead_code)]
pub fn root() -> std::path::PathBuf {
let here = std::path::Path::new(env!("CARGO_MANIFEST_DIR"));
if let Some(dir) = std::env::var_os("SHENG_CORPUS") {
return dir.into();
}
here.ancestors()
.find(|dir| dir.join(".git").exists())
.unwrap_or(here)
.to_path_buf()
}
pub fn corpus_files(files: usize) -> Vec<Vec<u8>> {
walk(files, usize::MAX)
.into_iter()
.map(|(_, bytes)| bytes)
.collect()
}
pub fn corpus_bytes(bytes: usize) -> Vec<Vec<u8>> {
walk(usize::MAX, bytes)
.into_iter()
.map(|(_, bytes)| bytes)
.collect()
}
pub fn corpus_paths(files: usize) -> Vec<(std::path::PathBuf, Vec<u8>)> {
walk(files, usize::MAX)
}
fn walk(files: usize, bytes: usize) -> Vec<(std::path::PathBuf, Vec<u8>)> {
const KINDS: [&str; 10] = [
"rs", "zig", "go", "py", "ts", "tsx", "md", "toml", "sql", "swift",
];
let mut out: Vec<(std::path::PathBuf, Vec<u8>)> = Vec::new();
let mut held = 0usize;
let mut stack = vec![root()];
let full =
|out: &Vec<(std::path::PathBuf, Vec<u8>)>, held: usize| out.len() >= files || held >= bytes;
while let Some(dir) = stack.pop() {
if full(&out, held) {
break;
}
let Ok(entries) = std::fs::read_dir(&dir) else {
continue;
};
for entry in entries.flatten() {
let path = entry.path();
let name = entry.file_name();
let name = name.to_string_lossy();
if name.starts_with('.') || matches!(&*name, "target" | "node_modules" | "vendor") {
continue;
}
if path.is_dir() {
stack.push(path);
continue;
}
let ext = path.extension().and_then(|e| e.to_str()).unwrap_or("");
if !KINDS.contains(&ext) {
continue;
}
if let Ok(text) = std::fs::read(&path)
&& !text.is_empty()
{
held += text.len();
out.push((path, text));
}
if full(&out, held) {
break;
}
}
}
out
}
pub fn host() -> String {
let cores = std::thread::available_parallelism().map_or(0, std::num::NonZero::get);
format!(
"{} {} · {cores} logical cores · {:?} kernel",
std::env::consts::OS,
std::env::consts::ARCH,
sheng::shuffle::kernel()
)
}
pub fn today() -> String {
let secs = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.map_or(0, |d| d.as_secs());
#[allow(clippy::cast_possible_wrap)]
let days = (secs / 86_400) as i64;
let z = days + 719_468; let era = z.div_euclid(146_097); let doe = z.rem_euclid(146_097);
let yoe = (doe - doe / 1460 + doe / 36_524 - doe / 146_096) / 365;
let doy = doe - (365 * yoe + yoe / 4 - yoe / 100);
let mp = (5 * doy + 2) / 153; let day = doy - (153 * mp + 2) / 5 + 1;
let month = if mp < 10 { mp + 3 } else { mp - 9 };
let year = yoe + era * 400 + i64::from(month <= 2);
format!("{year:04}-{month:02}-{day:02}")
}