use std::fs; use std::io; use std::path::{Path, PathBuf}; /// Resource payload that can be either borrowed from mapped bytes or owned. #[derive(Clone, Debug)] pub enum ResourceData<'a> { Borrowed(&'a [u8]), Owned(Vec), } impl<'a> ResourceData<'a> { pub fn as_slice(&self) -> &[u8] { match self { Self::Borrowed(slice) => slice, Self::Owned(buf) => buf.as_slice(), } } pub fn into_owned(self) -> Vec { match self { Self::Borrowed(slice) => slice.to_vec(), Self::Owned(buf) => buf, } } } impl AsRef<[u8]> for ResourceData<'_> { fn as_ref(&self) -> &[u8] { self.as_slice() } } /// Output sink used by `read_into`/`load_into` APIs. pub trait OutputBuffer { /// Writes the full payload to the sink, replacing any previous content. fn write_exact(&mut self, data: &[u8]) -> io::Result<()>; } impl OutputBuffer for Vec { fn write_exact(&mut self, data: &[u8]) -> io::Result<()> { self.clear(); self.extend_from_slice(data); Ok(()) } } /// Recursively collects all files under `root`. pub fn collect_files_recursive(root: &Path, out: &mut Vec) { let Ok(entries) = fs::read_dir(root) else { return; }; for entry in entries.flatten() { let path = entry.path(); if path.is_dir() { collect_files_recursive(&path, out); } else if path.is_file() { out.push(path); } } }