#tuple #tool #utils

map_tuple

Map individual elements of a tuple

4 releases

0.1.3 Nov 18, 2023
0.1.2 Nov 17, 2023
0.1.1 Nov 17, 2023
0.1.0 Nov 17, 2023

#1556 in Rust patterns

MIT/Apache

12KB
172 lines

Map Tuple

Provides traits to allow map()ing specific elements of a tuple. See docs for details.

This differs from the tuple-map crate in that the elements of the tuple don't have to be of the same type, and can be mapped to unique different types.


lib.rs:

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).

Dependencies