Introducing Tuple Tricks
Do you ever wish you could do more with tuples, without manually coding cases for each tuple length? What about tedious cases of mapping each type to a wrapper struct like a Result or Option? I know I do. If that sounds interesting to you, then tuple\_tricks might be for you. The basic idea is to allow induction on tuples, so if you can define your trait on a tuple of length one, and given a tuple of length n you can define it recursively for a tuple of length n+1. Github repo here: tuple\_tricks.
This actually came out of a desire to automate de-serialising tuples of structs from select statements while playing around with SPI in pgx. But as another example, I've implemented a simple method for tuple addition:
fn main() {
let smol = true;
let small = 1u8;
let mid = 1u16;
let big = 1u32;
let bigg = 1u64;
let biggg = 1u128;
let left_tuple = (smol, small, mid).t() + (big, bigg, biggg).t();
let right_tuple = (smol, small, mid, big, bigg, biggg);
assert_eq!(left_tuple.unwrap(), right_tuple);
}
(The .t() and .unwrap() are because I have to implement a wrapper type in order to implemented a custom std::ops::Add).
There currently appears to be a small runtime cost, but a bigger downside I can envision with these kinds of generalised abstract traits is inscrutable type errors in the compiler if some small trait condition is missing (e.g. you only want something to work with tuples of Copy types, but forget to implement Copy for your specific struct).
I'd love to get y'all's feedback on this.