Some checks failed
continuous-integration/drone/push Build is failing
Signed-off-by: kjuulh <contact@kjuulh.io>
139 lines
3.4 KiB
Rust
139 lines
3.4 KiB
Rust
#[derive(Clone, Default)]
|
|
pub struct FileReader {}
|
|
|
|
use std::{
|
|
collections::BTreeMap,
|
|
path::{Path, PathBuf},
|
|
};
|
|
|
|
pub mod extensions;
|
|
|
|
use anyhow::{anyhow, Context};
|
|
|
|
impl FileReader {
|
|
pub fn new() -> Self {
|
|
Self::default()
|
|
}
|
|
|
|
pub async fn read_files(&self, location: PathBuf) -> anyhow::Result<Files> {
|
|
tracing::trace!("reading files: {}", location.display());
|
|
|
|
let mut clusters: BTreeMap<String, Vec<File>> = BTreeMap::new();
|
|
|
|
let mut dir = tokio::fs::read_dir(&location)
|
|
.await
|
|
.context(format!("failed to find location: {}", &location.display()))?;
|
|
while let Some(dir_entry) = dir.next_entry().await? {
|
|
if dir_entry.metadata().await?.is_dir() {
|
|
tracing::trace!("found cluster in: {}", dir_entry.path().display());
|
|
clusters.insert(
|
|
dir_entry
|
|
.file_name()
|
|
.into_string()
|
|
.map_err(|_| anyhow!("failed to convert file name to string"))?,
|
|
Vec::new(),
|
|
);
|
|
}
|
|
}
|
|
|
|
for (cluster_name, files) in clusters.iter_mut() {
|
|
for file in walkdir::WalkDir::new(location.join(cluster_name))
|
|
.into_iter()
|
|
.flatten()
|
|
{
|
|
if !file.file_type().is_file() {
|
|
continue;
|
|
}
|
|
|
|
tracing::trace!(
|
|
"adding file: {} to cluster: {}",
|
|
file.path().display(),
|
|
cluster_name
|
|
);
|
|
|
|
if file.path().is_absolute() {
|
|
files.push((file.path(), file.path().strip_prefix(&location)?).into())
|
|
} else {
|
|
files.push(file.into_path().into())
|
|
}
|
|
}
|
|
}
|
|
|
|
Ok(clusters.into())
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct File {
|
|
pub path: PathBuf,
|
|
pub relative: Option<PathBuf>,
|
|
}
|
|
|
|
impl From<PathBuf> for File {
|
|
fn from(value: PathBuf) -> Self {
|
|
Self {
|
|
path: value,
|
|
relative: None,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<(PathBuf, PathBuf)> for File {
|
|
fn from(value: (PathBuf, PathBuf)) -> Self {
|
|
Self {
|
|
path: value.0,
|
|
relative: Some(value.1),
|
|
}
|
|
}
|
|
}
|
|
impl From<(&Path, &Path)> for File {
|
|
fn from(value: (&Path, &Path)) -> Self {
|
|
Self {
|
|
path: value.0.to_path_buf(),
|
|
relative: Some(value.1.to_path_buf()),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Default, Clone, Debug)]
|
|
pub struct Files {
|
|
inner: BTreeMap<String, Vec<File>>,
|
|
}
|
|
|
|
impl From<BTreeMap<String, Vec<File>>> for Files {
|
|
fn from(value: BTreeMap<String, Vec<File>>) -> Self {
|
|
Self { inner: value }
|
|
}
|
|
}
|
|
|
|
impl std::ops::Deref for Files {
|
|
type Target = BTreeMap<String, Vec<File>>;
|
|
|
|
fn deref(&self) -> &Self::Target {
|
|
&self.inner
|
|
}
|
|
}
|
|
|
|
impl From<Files> for Vec<File> {
|
|
fn from(value: Files) -> Self {
|
|
value
|
|
.iter()
|
|
.map(|(cluster_name, files)| (PathBuf::from(cluster_name), files))
|
|
.flat_map(|(_cluster_name, files)| files.to_vec())
|
|
// .map(|f| f.into())
|
|
.collect::<Vec<_>>()
|
|
}
|
|
}
|
|
|
|
impl IntoIterator for Files {
|
|
type Item = File;
|
|
|
|
type IntoIter = std::vec::IntoIter<Self::Item>;
|
|
|
|
fn into_iter(self) -> Self::IntoIter {
|
|
let files: Vec<File> = self.into();
|
|
|
|
files.into_iter()
|
|
}
|
|
}
|