tupley 0.0.13

Extension for primitive tuple (Hlist based on recursive structure)
Documentation
tupley-0.0.13 has been yanked.

tupley

Intro

Extension for primitive tuple (Hlist based on recursive structure).
You could use it to contain elements with different types

Struct

Basic structure:

struct Tuple<First, Tail>(First, Tail);   // NonEmpty Tuple
struct Unit                               // Empty Tuple used as last element

impl TupleY for Unit {
    const LEN: usize = 0;
    /** **/
}
impl<First, Tail: TupleY> TupleY for Tuple<First, Tail> {
    const LEN: usize = <Tail as TupleY>::LEN + 1;
    /** ...  **/
}
let t = tup!(1, 2.0, false);
// Tuple(1, Tuple(2.0, Tuple(false, Unit)))

Usage

  • create new tuple:
let t = tup!();
assert_eq!(t, Unit);

let t = tup!(1);
assert_eq!(t, Tuple(1, Unit));

let t = tup!(1, 2.0, "3");
assert_eq!(t, Tuple(1, Tuple(2.0, Tuple("3", Unit))));
  • check empty:
let t = tup!();
assert!(t.is_empty());

let t = tup!(1, false);
assert!(!t.is_empty());
  • pass on type:
let t = <tup_t!(i32, &str, bool)>::default();
// let t: tup_t!(i32, &str, bool) = Default::default();

assert_eq!(t, tup!(0, "", false));
  • pattern macth:
let t = tup!();
let tup_pat!() = t;

let t = tup!(1);
let tup_pat!(a) = t;
assert_eq!(a, tup!(1));

let t = tup!("", 2, 3.0);
let tup_pat!(a, b, c) = t;
assert_eq!(a, "");
assert_eq!(b, 2);
assert_eq!(c, tup!(3.0));

// don't match anything
let t = tup!(1, 2, 3, 4, 5);
let tup_pat!(..) = t;

let t = tup!(1, 2.0, "", vec![1], true);
let tup_pat!(a, b, c) = t;
assert_eq!(a, 1);
assert_eq!(b, 2.0);
assert_eq!(c, tup!("", vec![1], true)); // match the rest all
  • get length of every tuple:
let t = tup!();
assert_eq!(0, t.len());

let t = tup!(1, false);
assert_eq!(2, t.len());

let t = tup!(1, 2, 3);
assert_eq!(3, t.len());
  • add/combine two tuples into one (or pushing back/front new element)
let t1 = tup!(1, 2);
let t2 = tup!(3.0, false, Some(1));
let t = t1 + t2;
assert_eq!(t, tup!(1, 2, 3.0, false, Some(1)));

let t = tup!();
let t = t.push_back(1);
let t = t.push_back("str");
let t = t.push_back(false);
assert_eq!(t, tup!(1, "str", false));

let t = tup!();
let t = t.push_front(1);
let t = t.push_front("str");
let t = t.push_front(false);
assert_eq!(t, tup!(false, "str", 1));
  • functor map as_ref/as_mut/to_some/to_ok:
let t = tup!(1, "str", 3.0, false);
assert_eq!(t.as_ref(), tup!(&1, &"str", &3.0, &false));

let mut t = tup!(1, "str", 3.0, false);
assert_eq!(t.as_mut(), tup!(&mut 1, &mut "str", &mut 3.0, &mut false));

let t = tup!(1, "str", 3.0, false);
assert_eq!(t.to_some(), tup!(Some(1), Some("str"), Some(3.0), Some(false)));

let t = tup!(1, "str", 3.0, false);
assert_eq!(t.to_ok::<()>(), tup!(Ok(1), Ok("str"), Ok(3.0), Ok(false)));
  • check length in compile-time for tuples passed in (using const generics):
let t = tup!(1, 2, 3);

fn eq_yes<T: TupleLenEq<3>>(_: T) {}
eq_yes(t);


fn gt_yes_1<T: TupleLenGt<3>>(_: T) {}
gt_yes_1(t);

fn gt_yes_2<T: TupleLenGt<2>>(_: T) {}
gt_yes_2(t);


// The following will failed in compile time

// fn gt_err<T: TupleLenGt<4>>(_: T) {}  gt_err(t);

// fn eq_err<T: TupleLenEq<2>>(_: T) {}  eq_err(t);

More work WIP.