mirror of
https://git.sr.ht/~adnano/kiln
synced 2024-05-24 18:16:04 +02:00
95 lines
2.3 KiB
Rust
95 lines
2.3 KiB
Rust
use std::path::{Path, PathBuf};
|
|
use std::{env, fs, ops, slice};
|
|
|
|
use std::io::Result;
|
|
|
|
#[derive(Default)]
|
|
pub struct Index(Vec<(PathBuf, Vec<u8>)>);
|
|
|
|
impl Index {
|
|
pub fn from(dir: impl AsRef<Path>) -> Result<Index> {
|
|
let input = dir.as_ref();
|
|
let output = Path::new("");
|
|
let mut index = Index::default();
|
|
IndexDir::new(input, output, &mut index).index()?;
|
|
Ok(index)
|
|
}
|
|
|
|
pub fn len(&self) -> usize {
|
|
self.0.len()
|
|
}
|
|
|
|
pub fn insert(&mut self, key: PathBuf, val: Vec<u8>) {
|
|
self.0.push((key, val));
|
|
}
|
|
|
|
pub fn remove(&mut self, index: usize) {
|
|
self.0.remove(index);
|
|
}
|
|
|
|
pub fn iter_mut(&mut self) -> slice::IterMut<(PathBuf, Vec<u8>)> {
|
|
self.0.iter_mut()
|
|
}
|
|
|
|
pub fn write(&self, output: impl AsRef<Path>) -> Result<()> {
|
|
let output = output.as_ref();
|
|
if output.exists() {
|
|
// empty the output directory
|
|
fs::remove_dir_all(output)?;
|
|
}
|
|
fs::create_dir_all(output)?;
|
|
env::set_current_dir(output)?;
|
|
for (path, contents) in &self.0 {
|
|
if let Some(parent) = path.parent() {
|
|
fs::create_dir_all(&parent)?;
|
|
}
|
|
fs::write(&path, &contents)?;
|
|
}
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
impl ops::Index<usize> for Index {
|
|
type Output = (PathBuf, Vec<u8>);
|
|
fn index(&self, i: usize) -> &(PathBuf, Vec<u8>) {
|
|
&self.0[i]
|
|
}
|
|
}
|
|
|
|
impl ops::IndexMut<usize> for Index {
|
|
fn index_mut(&mut self, i: usize) -> &mut (PathBuf, Vec<u8>) {
|
|
&mut self.0[i]
|
|
}
|
|
}
|
|
|
|
struct IndexDir<'a> {
|
|
input: &'a Path,
|
|
output: &'a Path,
|
|
index: &'a mut Index,
|
|
}
|
|
|
|
impl<'a> IndexDir<'a> {
|
|
fn new(input: &'a Path, output: &'a Path, index: &'a mut Index) -> IndexDir<'a> {
|
|
IndexDir {
|
|
input,
|
|
output,
|
|
index,
|
|
}
|
|
}
|
|
|
|
fn index(self) -> Result<()> {
|
|
for entry in fs::read_dir(self.input)? {
|
|
let path = entry?.path();
|
|
let mut output = self.output.to_path_buf();
|
|
output.push(path.file_name().unwrap());
|
|
if path.is_file() {
|
|
let contents = fs::read(&path)?;
|
|
self.index.insert(output, contents);
|
|
} else if path.is_dir() {
|
|
IndexDir::new(&path, &output, self.index).index()?;
|
|
}
|
|
}
|
|
Ok(())
|
|
}
|
|
}
|