proton_launch/command/
move_compat.rs1use std::path::{Path, PathBuf};
2
3use crate::{paths::Paths, steam::SteamData};
4
5use super::{Runnable, RunnableResult};
6
7#[derive(Debug, Clone)]
8#[cfg_attr(feature = "commandline", derive(clap::ValueEnum))]
9enum MoveDirection {
10 GlobalToLocal,
12 LocalToGlobal,
14}
15
16#[derive(Debug, Clone)]
17#[cfg_attr(feature = "commandline", derive(clap::Args))]
18pub struct MoveCompat {
19 direction: MoveDirection,
21
22 exe: PathBuf,
24
25 #[cfg_attr(feature = "commandline", clap(short, long))]
28 save_name: Option<String>,
29}
30
31impl Runnable for MoveCompat {
32 fn run(&self, paths: &Paths, _steam_data: &SteamData) -> RunnableResult<()> {
33 let save_name = self
34 .save_name
35 .as_deref()
36 .unwrap_or_else(|| self.exe.file_stem().unwrap().to_str().unwrap());
37 let global_compat_dir = paths.compat_dir(save_name);
38 let local_compat_dir = self.exe.parent().unwrap().join("compat");
39 println!("global exists: {}", global_compat_dir.exists());
40 println!("local exists: {}", local_compat_dir.exists());
41 match self.direction {
42 MoveDirection::GlobalToLocal => {
43 println!(
44 "Moving compat folder from {} to {}",
45 global_compat_dir.display(),
46 local_compat_dir.display()
47 );
48 copy_file_tree(&global_compat_dir, &local_compat_dir).unwrap();
49 }
50 MoveDirection::LocalToGlobal => {
51 println!(
52 "Moving compat folder from {} to {}",
53 local_compat_dir.display(),
54 global_compat_dir.display()
55 );
56 copy_file_tree(&local_compat_dir, &global_compat_dir).unwrap();
57 }
58 };
59 Ok(())
60 }
61}
62
63fn copy_file_tree(source: &Path, dest: &Path) -> Result<(), std::io::Error> {
64 std::fs::create_dir_all(dest)?;
65 for entry in walkdir::WalkDir::new(source) {
66 let entry = entry?;
67 let path = entry.path().strip_prefix(source).unwrap();
68 if entry.file_type().is_dir() {
69 std::fs::create_dir_all(&dest.join(path))?;
70 } else if entry.file_type().is_file() {
71 std::fs::copy(entry.path(), &dest.join(path))?;
72 }
73 }
74
75 Ok(())
76}