68 lines
1.6 KiB
Rust
68 lines
1.6 KiB
Rust
use {
|
|
rand::Rng,
|
|
std::{
|
|
env,
|
|
fs::{self, DirEntry},
|
|
io::{self, Write},
|
|
path::PathBuf,
|
|
},
|
|
};
|
|
|
|
fn get_datadirs() -> Vec<PathBuf> {
|
|
let mut dirs = match env::var("XDG_DATA_DIRS") {
|
|
Ok(dirs) => dirs
|
|
.split(':')
|
|
.map(PathBuf::from)
|
|
.map(|mut p| {
|
|
p.push("42");
|
|
p
|
|
})
|
|
.collect(),
|
|
Err(_) => vec![
|
|
PathBuf::from("/usr/local/share/42"),
|
|
PathBuf::from("/usr/share/42"),
|
|
],
|
|
};
|
|
if let Ok(home) = env::var("HOME") {
|
|
let hddir = [&home, ".local", "share", "42"].iter().collect();
|
|
dirs.push(hddir);
|
|
}
|
|
dirs
|
|
}
|
|
|
|
fn is_file(entry: &DirEntry) -> bool {
|
|
if let Ok(t) = entry.file_type() {
|
|
if t.is_file() {
|
|
return true;
|
|
}
|
|
}
|
|
false
|
|
}
|
|
|
|
fn get_files() -> Vec<PathBuf> {
|
|
let mut files = vec![];
|
|
get_datadirs().iter().for_each(|d| {
|
|
if d.exists() {
|
|
if let Ok(dir) = fs::read_dir(&d) {
|
|
dir.filter(|e| e.is_ok())
|
|
.filter(|e| is_file(e.as_ref().unwrap()))
|
|
.map(|e| e.unwrap().path())
|
|
.for_each(|f| files.push(f));
|
|
}
|
|
}
|
|
});
|
|
files
|
|
}
|
|
|
|
fn main() -> Result<(), io::Error> {
|
|
let files = get_files();
|
|
let len = files.len();
|
|
let mut rng = rand::thread_rng();
|
|
let idx = rng.gen_range(0..len);
|
|
if let Some(path) = files.get(idx) {
|
|
let contents = fs::read(path)?;
|
|
io::stdout().write_all(&contents)?;
|
|
}
|
|
Ok(())
|
|
}
|