1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
use core::fmt;
use std::{ffi::OsStr, path::Path, sync::Arc};
use clap::{parser::ValueSource, ArgMatches, Command, FromArgMatches};
pub const INPUT: &str = if cfg!(feature = "sqlite") {
"RS3_CACHE_INPUT_FOLDER"
} else if cfg!(feature = "dat2") {
"OSRS_CACHE_INPUT_FOLDER"
} else if cfg!(feature = "dat") {
"LEGACY_CACHE_INPUT_FOLDER"
} else {
unimplemented!()
};
use std::ffi::OsString;
#[derive(Clone, Debug, Default)]
pub enum CachePath {
#[default]
Default,
Env(Arc<Path>),
CommandLine(Arc<Path>),
Argument(Arc<Path>),
}
impl fmt::Display for CachePath {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let path = self.as_ref();
#[cfg(not(target_arch = "wasm32"))]
let path = ::path_absolutize::Absolutize::absolutize(path).unwrap_or(std::borrow::Cow::Borrowed(path));
fmt::Display::fmt(&path.display(), f)
}
}
impl AsRef<Path> for CachePath {
fn as_ref(&self) -> &Path {
match self {
CachePath::Default => Path::new(""),
CachePath::Env(p) | CachePath::CommandLine(p) | CachePath::Argument(p) => p,
}
}
}
impl FromArgMatches for CachePath {
fn from_arg_matches(matches: &ArgMatches) -> Result<Self, clap::Error> {
let default = OsString::default();
let path: &OsString = matches.try_get_one("input").unwrap().unwrap_or(&default);
let path: Arc<Path> = Path::new(path).into();
let ret = match matches.value_source("input") {
Some(ValueSource::EnvVariable) => CachePath::Env(path),
Some(ValueSource::CommandLine) => CachePath::CommandLine(path),
_ => CachePath::Default,
};
Ok(ret)
}
fn update_from_arg_matches(&mut self, _matches: &ArgMatches) -> Result<(), clap::Error> {
Ok(())
}
}
impl clap::Args for CachePath {
fn augment_args(cmd: Command) -> Command {
let arg = clap::Arg::new("input")
.value_name("INPUT")
.help("The path where to look for the current cache")
.long("input")
.env(INPUT)
.default_value(OsStr::new("..."))
.value_parser(clap::builder::OsStringValueParser::new())
.required(false);
cmd.arg(arg)
}
fn augment_args_for_update(cmd: Command) -> Command {
let arg = clap::Arg::new("input")
.value_name("INPUT")
.help("The path where to look for the current cache")
.long("input")
.env(INPUT)
.default_value(OsStr::new("..."))
.value_parser(clap::builder::OsStringValueParser::new())
.required(false);
cmd.arg(arg)
}
}
pub struct LocationHelp<'p>(pub &'p CachePath);
impl fmt::Display for LocationHelp<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.0 {
CachePath::CommandLine(path) => writeln!(f, "looking in this directory because `--input {path:?}` was given on the command line")?,
CachePath::Argument(path) => writeln!(
f,
"looking in this directory because the path {path:?} was given as as a function argument"
)?,
CachePath::Env(path) => writeln!(
f,
"looking in this directory because the path {path:?} was retrieved from the `{INPUT}` environment variable"
)?,
CachePath::Default => writeln!(f, "looking in the current directory because no path was given")?,
}
Ok(())
}
}