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

Implement Predicate<PathBuf> for BinaryFilePredicate #74

Open
asomers opened this issue Feb 1, 2019 · 7 comments
Open

Implement Predicate<PathBuf> for BinaryFilePredicate #74

asomers opened this issue Feb 1, 2019 · 7 comments

Comments

@asomers
Copy link
Contributor

asomers commented Feb 1, 2019

It would be handy if BinaryFilePredicate implemented Predicate<PathBuf>. There are some functions that, for lifetime reasons, must take a 'static argument, like PathBuf. Right now those functions can't easily use predicates.

@epage
Copy link
Contributor

epage commented Feb 2, 2019

I just gave it a try and didn't have any problems

#!/usr/bin/env run-cargo-script
//! ```cargo
//! [package]
//! edition="2018"
//! [dependencies]
//! predicates = "1"
//! ```
use predicates::prelude::*;
fn main() {
    let actual = std::path::PathBuf::from("Cargo.toml");
    let expected = std::path::PathBuf::from("Cargo.toml");
    let pred = predicate::path::eq_file(expected);
    println!("{}", pred.eval(actual.as_path()));
}

Could you clarify where you are having lifetime problems at?

@asomers
Copy link
Contributor Author

asomers commented Feb 2, 2019

It worked for you because of that as_path() on the last line. In my case I'm using predicates from a generic function, so I can't do that.

@epage
Copy link
Contributor

epage commented Feb 2, 2019

Could you provide an example so I can better understand the constraints and we can work out how predicates might be able to change to make it work?

@asomers
Copy link
Contributor Author

asomers commented Feb 2, 2019

It's basically like this. The matches function doesn't know anything about what type it's handling. It's not very critical for me, though.

#!/usr/bin/env run-cargo-script
//! ```cargo
//! [package]
//! edition="2018"
//! [dependencies]
//! predicates = "1"
//! ```

fn matches<T, P: Predicate<T>>(value: &T, predicate: P) -> bool {
    predicate.eval(value)
}

use predicates::prelude::*;
fn main() {
    let actual = std::path::PathBuf::from("Cargo.toml");
    let expected = std::path::PathBuf::from("Cargo.toml");
    let pred = predicate::path::eq_file(expected);
    println!("{}", matches(&actual, pred));
}

@epage
Copy link
Contributor

epage commented Feb 2, 2019

Thanks for the example. For me to better understand the needs / use cases, is there a reason matches(actual.as_path(), pred) isn't sufficient?

@asomers
Copy link
Contributor Author

asomers commented Feb 4, 2019

Well, there's more generic code in front of that matches, and that code takes its argument by value, like this:

#!/usr/bin/env run-cargo-script
//! ```cargo
//! [package]
//! edition="2018"
//! [dependencies]
//! predicates = "1"
//! ```

fn do_something_with_value<T>(_value: T) {
}

fn do_something_with_value_if_it_matches<T, P>(value: T, predicate: P)
    where P: Predicate<T>
{
    if matches(&value, predicate) {
        do_something_with_value(value)
    }
}

fn matches<T, P: Predicate<T>>(value: &T, predicate: P) -> bool {
    predicate.eval(value)
}

use predicates::prelude::*;
fn main() {
    let actual = std::path::PathBuf::from("Cargo.toml");
    let expected = std::path::PathBuf::from("Cargo.toml");
    let pred = predicate::path::eq_file(expected);
    do_something_with_value_if_it_matches(actual, pred);
}

@epage
Copy link
Contributor

epage commented Feb 5, 2019

btw this is related to #20 where I ran into a lot of problems solving this generically.

Some options

  • We might be able to have blanket impls that translate PathBuf predicates into Path predicates
  • We can add owned type impl Predicate to each of our predicates
  • Don't know if I looked into whether AsRef / Deref / Borrow are object safe, allowing us to take &dyn AsRef<Path>.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants