Crate map_tuple

source ·
Expand description

Map Tuple

This crate provides traits that allow map()ing of tuple elements of different types to other types like so:

use map_tuple::*;

let tuple = (0i32, 1.0f32, 2i32, true, 4i32)
    .map3(|val| if val {3i64} else {0})
    .map0(|val| val.to_string())
    .map1(|val| Some(val))
    .map4(|val| val > 3);

assert_eq!(tuple, ("0".to_string(), Some(1.0f32), 2i32, 3i64, true));

Features

Because rust doesn’t allow reasoning about tuples generically, each tuple trait has to be implemented for each size of tuple explicitly. This crate provides 4 levels of tuple sizing (which includes all sizes of tuples below it):

  • 8 (default, no features enabled)
  • 16 (feature tuple16)
  • 32 (feature tuple32)
  • 64 (feature tuple64)
  • 128 (feature tuple128)

Adding additional sizes of tuples is trivially easy, so arbitrary sizes were chosen. In my experience, tuples don’t get much larger than 5-10, so having up to 128 available should be beyond sufficient for most, if not all, purposes.

To save my sanity, macros are used to simplify this process and make it more scalable. However, this does add some additional compilation time as the macros are expanded. To compound this, compiling rust generics tends to take a long time in and of itself, so every addition of another size of tuple increases compilation time exponentially.

For example, on an i5-8400, the following are the debug compilation times for the various features/tuple sizes:

  • no features (8) => 0.09s
  • tuple16 => 0.24s
  • tuple32 => 1.26s
  • tuple64 => 9.21s
  • tuple128 => 76s

If, for some unholy reason, you happen to need tuples larger than 128, I highly recommend you reconsider and try to use a struct, vec, enum, or some combination of those. However, if you really want it, a pull request can be created, and larger tuples can be added in a new release (this will not be considered a breaking change).

Traits