Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- use std::rc::Rc;
- use std::marker::PhantomData;
- fn main() {
- let john = User { name: "John".to_owned(), age: 16 };
- let not_john = User { name: "Paul".to_owned(), age: 18 };
- let prop_name = Property::new(&"name", User::name);
- let is_john = prop_name.eq("John".to_owned());
- println!("{}", (is_john.predicate)(&john)); // should return true
- println!("{}", (is_john.predicate)(¬_john)); // should return false
- }
- struct User {
- name: String,
- age: i32,
- }
- impl User {
- fn name(&self) -> String {
- self.name.to_owned()
- }
- fn age(&self) -> i32 {
- self.age
- }
- }
- struct Property<T, R> {
- name: String,
- selector: Rc<Fn(&T) -> R>,
- }
- impl<T, R> Property<T, R> {
- fn new<S: 'static>(name: &str, selector: S) -> Property<T, R>
- where S: Fn(&T) -> R {
- Property { name: name.to_owned(), selector: Rc::new(selector) }
- }
- }
- struct Feature<T, F: Fn(&T) -> bool> {
- description: String,
- // this gets rid of the unnecessary box, and allows
- // us to annotate the lifetime of the function
- predicate: F,
- // treat this as extra necessary syntax if you don't understand it
- __phantom: PhantomData<T>
- }
- impl<T, R: Eq> Property<T, R> {
- // note the impl Fn(&T) -> bool + '_
- // this means that we are making the compiler infer
- // the return type from the body of the function
- // '_ means that we are making the compiler infer
- // the correct lifetime (not 'static)
- fn eq(&self, data: R) -> Feature<T, impl Fn(&T) -> bool + '_> {
- Feature {
- description: self.name.to_owned() + "== fixed data",
- predicate: move |it: &T| (self.selector)(it) == data,
- __phantom: PhantomData
- }
- }
- }
Add Comment
Please, Sign In to add comment