fn_traits and unboxed_closures combine to make roundabout polymorphic functions!
#![feature(fn_traits)]
#![feature(unboxed_closures)]
#[allow(non_camel_case_types)]
struct add;
impl FnOnce<(usize, usize)> for add {
type Output = usize;
extern "rust-call" fn call_once(self, (a, b): (usize, usize)) -> usize {
a + b
}
}
impl FnOnce<(u32, u32, u32)> for add {
type Output = usize;
extern "rust-call" fn call_once(self, (a, b, c): (u32, u32, u32)) -> usize {
(a + b + c) as _
}
}
impl FnOnce<(&str, &str)> for add {
type Output = String;
extern "rust-call" fn call_once(self, (a, b): (&str, &str)) -> String {
let mut res = a.to_owned();
res += b;
res
}
}
fn main() {
dbg!(add(34, 35));
dbg!(add(23, 23, 23));
dbg!(add("hello ", "world!"));
}
Errors:
Compiling playground v0.0.1 (/playground)
Finished dev [unoptimized + debuginfo] target(s) in 0.52s
Running `target/debug/playground`
[src/main.rs:34] add(34, 35) = 69
[src/main.rs:35] add(23, 23, 23) = 69
[src/main.rs:36] add("hello ", "world!") = "hello world!"
Is it cursed? Yes! Is it overly verbose? Also yes! But it does work nonetheless to create "functions" that are able to be called using multiple types of data.