Skip to content

Instantly share code, notes, and snippets.

@Mathspy
Created October 19, 2021 15:58
Show Gist options
  • Save Mathspy/15ad816bba388f8bc9b81df13e08cb73 to your computer and use it in GitHub Desktop.
Save Mathspy/15ad816bba388f8bc9b81df13e08cb73 to your computer and use it in GitHub Desktop.
Get a breakdown of a directory
use std::{
collections::HashSet,
ffi::OsString,
fs,
hash::{Hash, Hasher},
path::Path,
};
#[derive(Debug, PartialEq, Eq)]
pub enum DirEntry {
Dir {
name: OsString,
entries: HashSet<DirEntry>,
},
File {
name: OsString,
},
}
impl Hash for DirEntry {
fn hash<H: Hasher>(&self, state: &mut H) {
match self {
DirEntry::Dir { name, .. } => name.hash(state),
DirEntry::File { name } => name.hash(state),
};
}
}
impl DirEntry {
pub fn dir<T>(from: &str, entries: T) -> Self
where
T: IntoIterator<Item = Self>,
{
DirEntry::Dir {
name: from.parse().unwrap(),
entries: entries.into_iter().collect(),
}
}
pub fn file(from: &str) -> Self {
DirEntry::File {
name: from.parse().unwrap(),
}
}
pub fn breakdown<P: AsRef<Path>>(path: P) -> Self {
if !path.as_ref().is_dir() {
todo!("DirEntry::breakdown currently only handles dir paths");
}
let entries = fs::read_dir(path.as_ref())
.expect("read directory")
.map(|result| result.expect("read directory files"))
.map(|dir_entry| {
(
dir_entry.file_name(),
dir_entry.file_type().expect("get file type from dir_entry"),
)
})
.map(
|(file_name, file_type)| match (file_type.is_dir(), file_type.is_file()) {
(true, false) => Self::breakdown(path.as_ref().join(&file_name)),
(false, true) => DirEntry::File { name: file_name },
_ => unimplemented!(),
},
)
.collect();
DirEntry::Dir {
name: path
.as_ref()
.file_name()
.expect("get name of dir in dir_breakdown")
.to_os_string(),
entries,
}
}
}
@Mathspy
Copy link
Author

Mathspy commented Oct 19, 2021

Special thanks to @memoryruins for being awesome even when I suck c: <3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment