Skip to content

Commit c65b9c4

Browse files
Merge pull request #25 from lu-zero/dyn-compatible
Make the traits dyn-compatible
2 parents f2bc664 + eea22be commit c65b9c4

File tree

9 files changed

+59
-63
lines changed

9 files changed

+59
-63
lines changed

src/app_strategy.rs

+5-13
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ use std::ffi::OsStr;
44
use std::path::Path;
55
use std::path::PathBuf;
66

7+
use crate::HomeDirError;
8+
79
/// The arguments to the creator method of an [`AppStrategy`](trait.AppStrategy.html).
810
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
911
pub struct AppStrategyArgs {
@@ -70,13 +72,7 @@ macro_rules! in_dir_method {
7072
}
7173

7274
/// Allows applications to retrieve the paths of configuration, data, and cache directories specifically for them.
73-
pub trait AppStrategy: Sized {
74-
/// The error type returned by `new`.
75-
type CreationError: std::error::Error;
76-
77-
/// The constructor requires access to some basic information about your application.
78-
fn new(args: AppStrategyArgs) -> Result<Self, Self::CreationError>;
79-
75+
pub trait AppStrategy {
8076
/// Gets the home directory of the current user.
8177
fn home_dir(&self) -> &Path;
8278

@@ -142,18 +138,14 @@ macro_rules! create_strategies {
142138
/// Returns the current OS’s native [`AppStrategy`](trait.AppStrategy.html).
143139
/// This uses the [`Windows`](struct.Windows.html) strategy on Windows, [`Apple`](struct.Apple.html) on macOS & iOS, and [`Xdg`](struct.Xdg.html) everywhere else.
144140
/// This is the convention used by most GUI applications.
145-
pub fn choose_native_strategy(
146-
args: AppStrategyArgs,
147-
) -> Result<$native, <$native as AppStrategy>::CreationError> {
141+
pub fn choose_native_strategy(args: AppStrategyArgs) -> Result<$native, HomeDirError> {
148142
<$native>::new(args)
149143
}
150144

151145
/// Returns the current OS’s default [`AppStrategy`](trait.AppStrategy.html).
152146
/// This uses the [`Windows`](struct.Windows.html) strategy on Windows, and [`Xdg`](struct.Xdg.html) everywhere else.
153147
/// This is the convention used by most CLI applications.
154-
pub fn choose_app_strategy(
155-
args: AppStrategyArgs,
156-
) -> Result<$app, <$app as AppStrategy>::CreationError> {
148+
pub fn choose_app_strategy(args: AppStrategyArgs) -> Result<$app, HomeDirError> {
157149
<$app>::new(args)
158150
}
159151
};

src/app_strategy/apple.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
use crate::base_strategy;
21
use crate::base_strategy::BaseStrategy;
2+
use crate::{base_strategy, HomeDirError};
33
use std::path::{Path, PathBuf};
44

55
/// This is the strategy created by Apple for use on macOS and iOS devices. It is always used by GUI apps on macOS, and is sometimes used by command-line applications there too. iOS only has GUIs, so all iOS applications follow this strategy. The specification is available [here](https://developer.apple.com/library/archive/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/FileSystemOverview/FileSystemOverview.html#//apple_ref/doc/uid/TP40010672-CH2-SW1).
@@ -49,16 +49,17 @@ pub struct Apple {
4949
bundle_id: String,
5050
}
5151

52-
impl super::AppStrategy for Apple {
53-
type CreationError = crate::HomeDirError;
54-
55-
fn new(args: super::AppStrategyArgs) -> Result<Self, Self::CreationError> {
52+
impl Apple {
53+
/// Create a new Apple AppStrategy
54+
pub fn new(args: super::AppStrategyArgs) -> Result<Self, HomeDirError> {
5655
Ok(Self {
5756
base_strategy: base_strategy::Apple::new()?,
5857
bundle_id: args.bundle_id().replace(' ', ""),
5958
})
6059
}
60+
}
6161

62+
impl super::AppStrategy for Apple {
6263
fn home_dir(&self) -> &Path {
6364
self.base_strategy.home_dir()
6465
}

src/app_strategy/unix.rs

+7-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
use std::path::{Path, PathBuf};
22

3+
use crate::HomeDirError;
4+
35
/// This strategy has no standard or official specification. It has arisen over time through hundreds of Unixy tools. Vim and Cargo are notable examples whose configuration/data/cache directory layouts are similar to those created by this strategy.
46
///
57
/// ```
@@ -48,16 +50,17 @@ pub struct Unix {
4850
unixy_name: String,
4951
}
5052

51-
impl super::AppStrategy for Unix {
52-
type CreationError = crate::HomeDirError;
53-
54-
fn new(args: super::AppStrategyArgs) -> Result<Self, Self::CreationError> {
53+
impl Unix {
54+
/// Create a new Unix AppStrategy
55+
pub fn new(args: super::AppStrategyArgs) -> Result<Self, HomeDirError> {
5556
Ok(Self {
5657
home_dir: crate::home_dir()?,
5758
unixy_name: format!(".{}", args.unixy_name()),
5859
})
5960
}
61+
}
6062

63+
impl super::AppStrategy for Unix {
6164
fn home_dir(&self) -> &Path {
6265
&self.home_dir
6366
}

src/app_strategy/windows.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
use crate::base_strategy;
21
use crate::base_strategy::BaseStrategy;
2+
use crate::{base_strategy, HomeDirError};
33
use std::path::{Path, PathBuf};
44

55
/// This strategy follows Windows’ conventions. It seems that all Windows GUI apps, and some command-line ones follow this pattern. The specification is available [here](https://docs.microsoft.com/en-us/windows/win32/shell/knownfolderid).
@@ -129,16 +129,17 @@ macro_rules! dir_method {
129129
}};
130130
}
131131

132-
impl super::AppStrategy for Windows {
133-
type CreationError = crate::HomeDirError;
134-
135-
fn new(args: super::AppStrategyArgs) -> Result<Self, Self::CreationError> {
132+
impl Windows {
133+
/// Create a new Windows AppStrategy
134+
pub fn new(args: super::AppStrategyArgs) -> Result<Self, HomeDirError> {
136135
Ok(Self {
137136
base_strategy: base_strategy::Windows::new()?,
138137
author_app_name_path: PathBuf::from(args.author).join(args.app_name),
139138
})
140139
}
140+
}
141141

142+
impl super::AppStrategy for Windows {
142143
fn home_dir(&self) -> &Path {
143144
self.base_strategy.home_dir()
144145
}

src/app_strategy/xdg.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
use crate::base_strategy;
21
use crate::base_strategy::BaseStrategy;
2+
use crate::{base_strategy, HomeDirError};
33
use std::path::{Path, PathBuf};
44

55
/// This strategy implements the [XDG Base Directories Specification](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html). It is the most common on Linux, but is increasingly being adopted elsewhere.
@@ -173,16 +173,17 @@ pub struct Xdg {
173173
unixy_name: String,
174174
}
175175

176-
impl super::AppStrategy for Xdg {
177-
type CreationError = crate::HomeDirError;
178-
179-
fn new(args: super::AppStrategyArgs) -> Result<Self, Self::CreationError> {
176+
impl Xdg {
177+
/// Create a new Xdg AppStrategy
178+
pub fn new(args: super::AppStrategyArgs) -> Result<Self, HomeDirError> {
180179
Ok(Self {
181180
base_strategy: base_strategy::Xdg::new()?,
182181
unixy_name: args.unixy_name(),
183182
})
184183
}
184+
}
185185

186+
impl super::AppStrategy for Xdg {
186187
fn home_dir(&self) -> &Path {
187188
self.base_strategy.home_dir()
188189
}

src/base_strategy.rs

+4-10
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,10 @@
11
//! These strategies simply provide the user’s configuration, data, and cache directories, without knowing about the application specifically.
22
3+
use crate::HomeDirError;
34
use std::path::{Path, PathBuf};
45

56
/// Provides configuration, data, and cache directories of the current user.
6-
pub trait BaseStrategy: Sized {
7-
/// The error type returned by `new`.
8-
type CreationError: std::error::Error;
9-
10-
/// Base strategies are constructed without knowledge of the application.
11-
fn new() -> Result<Self, Self::CreationError>;
12-
7+
pub trait BaseStrategy {
138
/// Gets the home directory of the current user.
149
fn home_dir(&self) -> &Path;
1510

@@ -42,15 +37,14 @@ macro_rules! create_strategies {
4237
/// Returns the current OS’s native [`BaseStrategy`](trait.BaseStrategy.html).
4338
/// This uses the [`Windows`](struct.Windows.html) strategy on Windows, [`Apple`](struct.Apple.html) on macOS & iOS, and [`Xdg`](struct.Xdg.html) everywhere else.
4439
/// This is the convention used by most GUI applications.
45-
pub fn choose_native_strategy() -> Result<$native, <$native as BaseStrategy>::CreationError>
46-
{
40+
pub fn choose_native_strategy() -> Result<$native, HomeDirError> {
4741
<$native>::new()
4842
}
4943

5044
/// Returns the current OS’s default [`BaseStrategy`](trait.BaseStrategy.html).
5145
/// This uses the [`Windows`](struct.Windows.html) strategy on Windows, and [`Xdg`](struct.Xdg.html) everywhere else.
5246
/// This is the convention used by most CLI applications.
53-
pub fn choose_base_strategy() -> Result<$base, <$base as BaseStrategy>::CreationError> {
47+
pub fn choose_base_strategy() -> Result<$base, HomeDirError> {
5448
<$base>::new()
5549
}
5650
};

src/base_strategy/apple.rs

+7-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
use std::path::{Path, PathBuf};
22

3+
use crate::HomeDirError;
4+
35
/// This is the strategy created by Apple for use on macOS and iOS devices. It is always used by GUI apps on macOS, and is sometimes used by command-line applications there too. iOS only has GUIs, so all iOS applications follow this strategy. The specification is available [here](https://developer.apple.com/library/archive/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/FileSystemOverview/FileSystemOverview.html#//apple_ref/doc/uid/TP40010672-CH2-SW1).
46
///
57
/// ```
@@ -40,16 +42,16 @@ use std::path::{Path, PathBuf};
4042
pub struct Apple {
4143
home_dir: PathBuf,
4244
}
43-
44-
impl super::BaseStrategy for Apple {
45-
type CreationError = crate::HomeDirError;
46-
47-
fn new() -> Result<Self, Self::CreationError> {
45+
impl Apple {
46+
/// Create a new Apple BaseStrategy
47+
pub fn new() -> Result<Self, HomeDirError> {
4848
Ok(Self {
4949
home_dir: crate::home_dir()?,
5050
})
5151
}
52+
}
5253

54+
impl super::BaseStrategy for Apple {
5355
fn home_dir(&self) -> &Path {
5456
&self.home_dir
5557
}

src/base_strategy/windows.rs

+9-8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
use std::path::{Path, PathBuf};
22

3+
use crate::HomeDirError;
4+
35
/// This strategy follows Windows’ conventions. It seems that all Windows GUI apps, and some command-line ones follow this pattern. The specification is available [here](https://docs.microsoft.com/en-us/windows/win32/shell/knownfolderid).
46
///
57
/// This initial example removes all the relevant environment variables to show the strategy’s use of the:
@@ -109,6 +111,13 @@ pub struct Windows {
109111
// Ref: https://github.com/rust-lang/cargo/blob/home-0.5.5/crates/home/src/windows.rs
110112
// We should keep this code in sync with the above.
111113
impl Windows {
114+
/// Create a new Windows BaseStrategy
115+
pub fn new() -> Result<Self, HomeDirError> {
116+
Ok(Self {
117+
home_dir: crate::home_dir()?,
118+
})
119+
}
120+
112121
fn dir_inner(env: &'static str) -> Option<PathBuf> {
113122
std::env::var_os(env)
114123
.filter(|s| !s.is_empty())
@@ -155,14 +164,6 @@ impl Windows {
155164
}
156165

157166
impl super::BaseStrategy for Windows {
158-
type CreationError = crate::HomeDirError;
159-
160-
fn new() -> Result<Self, Self::CreationError> {
161-
Ok(Self {
162-
home_dir: crate::home_dir()?,
163-
})
164-
}
165-
166167
fn home_dir(&self) -> &Path {
167168
&self.home_dir
168169
}

src/base_strategy/xdg.rs

+9-8
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
use std::path::Path;
22
use std::path::PathBuf;
33

4+
use crate::HomeDirError;
5+
46
/// This strategy implements the [XDG Base Directories Specification](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html). It is the most common on Linux, but is increasingly being adopted elsewhere.
57
///
68
/// This initial example removes all the XDG environment variables to show the strategy’s use of the XDG default directories.
@@ -157,6 +159,13 @@ pub struct Xdg {
157159
}
158160

159161
impl Xdg {
162+
/// Create a new Xdg BaseStrategy
163+
pub fn new() -> Result<Self, HomeDirError> {
164+
Ok(Self {
165+
home_dir: crate::home_dir()?,
166+
})
167+
}
168+
160169
fn env_var_or_none(env_var: &str) -> Option<PathBuf> {
161170
std::env::var(env_var).ok().and_then(|path| {
162171
let path = PathBuf::from(path);
@@ -176,14 +185,6 @@ impl Xdg {
176185
}
177186

178187
impl super::BaseStrategy for Xdg {
179-
type CreationError = crate::HomeDirError;
180-
181-
fn new() -> Result<Self, Self::CreationError> {
182-
Ok(Self {
183-
home_dir: crate::home_dir()?,
184-
})
185-
}
186-
187188
fn home_dir(&self) -> &Path {
188189
&self.home_dir
189190
}

0 commit comments

Comments
 (0)