Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Manually create a xdg::BaseDirectories value #44

Closed
piegamesde opened this issue May 14, 2022 · 7 comments · Fixed by #65
Closed

Manually create a xdg::BaseDirectories value #44

piegamesde opened this issue May 14, 2022 · 7 comments · Fixed by #65

Comments

@piegamesde
Copy link
Contributor

I'd like to mock some data for testing. I tried modifying environment variables at first but this failed because other parts of the application do rely on the real paths still being present

@whitequark
Copy link
Owner

This seems useful. I'm happy to merge a PR adding a new constructor creating a mock BaseDirectories value. (Something like xdg::BaseDirectories::with_mock_directories(...)?) Alternatively we could just make the fields public. I'm not sure if anything requires them to be private but on a quick glance it doesn't seem like anything does?

@julianandrews
Copy link
Contributor

julianandrews commented Jul 28, 2023

I started having a go at writing this and I'm having trouble coming up with an interface that isn't kind of ugly for the with_mock_directories() approach - it would need nine positional arguments, many of the same type, or some sort of opaque lambda, neither of which is a great public interface.

I think probably the best approach is either to make the fields public, or use some sort of builder pattern.

The builder pattern would probably look something like:

pub struct BaseDirectoriesBuilder { ... }

impl BaseDirectoriesBuilder {
        pub fn new() -> BaseDirectoriesBuilder { ... }

        pub fn with_prefix<P: AsRef<Path>>(prefix: P) -> BaseDirectoriesBuilder { ... }

        pub fn with_profile<P1, P2>(prefix: P1, profile: P2 -> BaseDirectoriesBuilder
        where
            P1: AsRef<Path>,
            P2: AsRef<Path>,
        { ... }

        pub fn with_data_home<P: AsRef<Path>>(self, data_home: P) -> BaseDirectoriesBuilder { ... }

        ...

        pub fn build(self) -> BaseDirectories {}
}

I'm leaning towards just making the fields public, and possibly adding a convenience method to build an "clean" instance. Something like:

impl BaseDirectories {
    pub fn empty() -> BaseDirectories {
        BaseDirectories {
            PathBuf::new(),
            PathBuf::new(),
            None,
            None,
            None,
            Vec::new(),
            Vec::new(),
            None,
    }
}

@whitequark - thoughts?

@piegamesde
Copy link
Contributor Author

piegamesde commented Jul 28, 2023

Looking at the current code, there already exists the with_env function, and it is also used for testing. So my proposal would be to extend all existing constructors with a _env variant where you can inject custom environment variables. Ideally, one could call them with std::env::var_os as function and get the same thing as the original constructors.

This would also allow thing like |var| match var { "XDG_DATA_HOME" => Some("/tmp"), _ => std::env::var_os(var) }, which I find rather elegant.

@whitequark
Copy link
Owner

Is there any downside at all to making the fields public?

@whitequark
Copy link
Owner

o my proposal would be to extend all existing constructors with a _env variant where you can inject custom environment variables. Ideally, one could call them with std::env::var_os as function and get the same thing as the original constructors.

But this looks sensible to me as well.

@piegamesde
Copy link
Contributor Author

About making the fields public, I'm not opposed to that it's just I don't know how the "prefix" fields interact with the other ones. Are there any invariants of any kind that should be upheld?

@whitequark
Copy link
Owner

I don't quite remember, I wrote this code many many years ago originally...

piegamesde added a commit to piegamesde/rust-xdg that referenced this issue Jul 30, 2023
piegamesde added a commit to piegamesde/rust-xdg that referenced this issue Jul 30, 2023
piegamesde added a commit to piegamesde/rust-xdg that referenced this issue Jul 30, 2023
whitequark pushed a commit that referenced this issue Jan 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants