Function to return different-shaped (generic?) function pointers


#1

Say I have two functions:

fn function_with_one_argument(one: i64) -> bool{
    one==one // irrelevant
}

fn function_with_two_arguments(one: i64, two: i64) -> bool {
    one==two // irrelevant
}

Given a different input value, I’d like to return a different function pointer:

fn main() {
    println!("\n\n{:?}\n\n", get_function_pointer(1)(321));
    println!("{:?}", get_function_pointer(2)(321/*, 321*/));
}

How can I represent the return value to return a pointer to different shaped functions?

fn get_function_pointer(id: i64) -> /***/(fn(i64) -> bool)/***/ {
    match id {
        1 => function_with_one_argument,
        // 2 => function_with_two_arguments, /*How do we make this work?*?
        _ => panic!("!?!?!")
    }
}

#2

How would you use the returned function if you do not know how many arguments it expects ?


#3

I’m feeding the function pointer to quickcheck as a prop.


#4

I think you can return anything as Box<Any>, but I’m not sure if you’ll be able to get the original function out of that back, since functions have very specific types that can’t be named.


#5

Here is a simplified version of what I ended up doing.

extern crate quickcheck;
use quickcheck::{QuickCheck, Testable};
use std::collections::HashMap;

fn main() {
    let mut property_map = HashMap::new();
    property_map.insert("one", Property::One{func: one_argument});
    property_map.insert("two", Property::Two{func: two_arguments});

    test_property("one", &property_map);
    test_property("two", &property_map);
}

enum Property {
    One{func: fn(i64)-> bool},
    Two{func: fn(i64, i64)->bool},
}

fn test_property(property: &str, property_map: &HashMap<&str, Property>) {
    match property_map.get(property) {
        Some(p) => fetch_property_and_run_quickcheck(p),
        None => println!("No matching property in property_map"),
    };
}

fn fetch_property_and_run_quickcheck(property: &Property){
    match *property {
        Property::One{func: prop_to_test} => run_quickcheck(prop_to_test),
        Property::Two{func: prop_to_test} => run_quickcheck(prop_to_test)
    };
}

fn run_quickcheck<A>(property: A) where A: Testable {
    QuickCheck::new().quickcheck(property);
}

fn one_argument(one: i64) -> bool{
    println!("testing one_argument() with {}", one);
    one==one // irrelevant
}

fn two_arguments(one: i64, two: i64) -> bool {
    println!("testing two_arguments() with {} and {}", one, two);
    one==one && two == two // irrelevant
}