added link_install_to_target

This commit is contained in:
2026-02-26 22:25:45 +01:00
parent bf04d48af4
commit 9fe7340530

View File

@@ -8,28 +8,25 @@ use crate::fomod::FileTypeEnum;
pub struct Linker { pub struct Linker {
target: PathBuf, target: PathBuf,
game_dir: PathBuf,
} }
impl Linker { impl Linker {
pub fn new(target_path: &Path) -> Self { pub fn new(target_path: &Path, game_dir: &Path) -> Self {
Self { Self {
target: target_path.to_owned(), target: target_path.to_owned(),
game_dir: game_dir.to_owned(),
} }
} }
#[inline]
fn install_path(&self) -> &Path {
&self.target
}
fn link_file(&self, from: &Path, to: &Path) -> Result<(), LinkerError> { fn link_file(&self, from: &Path, to: &Path) -> Result<(), LinkerError> {
let target = self.install_path().join(path_to_lowercase(to)); let target = self.target.join(path_to_lowercase(to));
if let Some(parent) = target.parent() { if let Some(parent) = target.parent() {
fs::create_dir_all(parent)?; fs::create_dir_all(parent)?;
} }
unix::fs::symlink(from, target)?; create_symlink_for_file(from, &target)?;
Ok(()) Ok(())
} }
@@ -80,19 +77,44 @@ impl Linker {
Ok(()) Ok(())
} }
pub fn link_install_to_target(&self) -> Result<(), LinkerError> {
fn symlink_tree(src: &Path, dst: &Path) -> Result<(), LinkerError> {
if !dst.exists() {
fs::create_dir_all(dst)?;
}
for entry in fs::read_dir(src)? {
let entry = entry?;
let src_path = entry.path();
let dst_path = dst.join(path_to_lowercase(&entry.path()).file_name().unwrap());
let meta = entry.metadata()?;
if meta.is_dir() {
symlink_tree(&src_path, &dst_path)?;
} else if meta.is_file() {
create_symlink_for_file(&src_path, &dst_path)?;
}
}
Ok(())
}
symlink_tree(&self.game_dir, &self.target)?;
Ok(())
}
} }
#[derive(Debug)] #[derive(Debug)]
pub enum LinkerError { pub enum LinkerError {
Io(io::Error), Io(io::Error),
NotASymlink(PathBuf),
} }
impl std::fmt::Display for LinkerError { impl std::fmt::Display for LinkerError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self { match self {
Self::Io(e) => write!(f, "IO error: {}", e), Self::Io(e) => write!(f, "IO error: {}", e),
Self::NotASymlink(path) => write!(f, "Tried to remove a non symlink: {:?}", path),
} }
} }
} }
@@ -108,3 +130,15 @@ impl From<io::Error> for LinkerError {
fn path_to_lowercase(path: &Path) -> PathBuf { fn path_to_lowercase(path: &Path) -> PathBuf {
PathBuf::from(path.to_string_lossy().to_lowercase()) PathBuf::from(path.to_string_lossy().to_lowercase())
} }
fn create_symlink_for_file(src: &Path, dst: &Path) -> io::Result<()> {
#[cfg(unix)]
{
unix::fs::symlink(src, dst)
}
#[cfg(windows)]
{
std::os::windows::fs::symlink_file(src, dst)
}
}