tuple_map/
lib.rs

1//! This library provides 'map' methods to Tuple.
2//! # Example
3//! ```
4//! extern crate tuple_map;
5//! use tuple_map::*;
6//! fn main() {
7//!     let (x, y) = (3, 4);
8//!     let (x, y) = (x, y).map(|a| a + 5);
9//!     assert_eq!(x, 8);
10//!     assert_eq!(y, 9);
11//!
12//!     let v = (3, 4, 5, 6).fold(vec![], |mut v, x| {
13//!         if x % 3 == 0 {
14//!             v.push(x);
15//!         }
16//!         v
17//!     });
18//!     assert_eq!(v, vec![3, 6]);
19//!
20//!     assert!((3, 3, 3).same());
21//!
22//!     assert_eq!((3, 4, 5).nth(1), Some(4));
23//!
24//!     assert_eq!((3, 4, 5).add((1, 2, 3)), (4, 6, 8));
25//!
26//!     let a = (1, 2, 3);
27//!     let b = ("a", "b", "c");
28//!     assert_eq!(
29//!         a.zipf(b, |x, y| format!("{}{}", x, y)),
30//!         ("1a", "2b", "3c").map(|x| x.to_owned())
31//!     );
32//!
33//!     assert_eq!(a.sum(), 6);
34//!
35//!     assert_eq!(a.tmax(), 3);
36//!     assert_eq!(a.tmin(), 1);
37//! }
38//! ```
39//!
40//! **Notes**
41//! This library defines different trait depending on the length of tuple,
42//! like `TupleMap1`, `TupleMap2`,..., by macro, so same docs are generated for each trait.
43macro_rules! impl_tuple_map {
44    ($trait: ident,
45     $($name_reduced: ident)*,
46     $($name: ident)+,
47     $($name2: ident)+,
48     $($item: ident)+,
49     $($self: ident)+,
50     $($other: ident)+) => {
51        pub trait $trait {
52            type Item;
53
54            /// Checks if every element of tuple matches a predicate, like
55            /// [`std::iter::Iterator::all`](https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.all).
56            /// 
57            /// This method take a closure returns `true` or `false`, and tries to apply this
58            /// closure to all elements of tuple. If and only if all of them returns `true`,
59            /// this method return `true`.
60            /// # Examples
61            /// ```ignore
62            /// let a = (3, 9, 12, ...);
63            /// assert!(a.all(|x| x % 3 == 0));
64            /// assert!(!a.all(|x| x % 4 == 0));
65            /// ```
66            fn all<F>(self, f: F) -> bool
67            where
68                F: FnMut(Self::Item) -> bool;
69
70            /// Checks if any element of tuple matches a predicate, like
71            /// [`std::iter::Iterator::any`](https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.all).
72            /// 
73            /// This method take a closure returns `true` or `false`, and tries to apply this
74            /// closure to all elements of tuple. If any of them returns `true`,
75            /// this method return `true`.
76            /// # Examples
77            /// ```ignore
78            /// let a = (3, 9, 12, ...);
79            /// assert!(a.any(|x| x % 4 == 0));
80            /// assert!(!a.any(|x| x % 7 == 0));
81            /// ```
82            fn any<F>(self, f: F) -> bool
83            where
84                F: FnMut(Self::Item) -> bool;
85
86            /// Takes `&(a, a, a, ...)` and returns `(&a, &a, &a, ...)`
87            /// # Examples
88            /// ```ignore
89            /// let a = (3, 3, 3, ...);
90            /// assert_eq!(a.by_ref(), (&3, &3, &3, ...));
91            /// ```
92            fn by_ref(&self) -> ($(&Self::$item, )*);
93
94            /// Takes `&mut (a, a, a, ...)` and returns `(&mut a, &mut a, &mut a, ...)`
95            /// # Examples
96            /// ```ignore
97            /// let a = (3, 3, 3, ...);
98            /// assert_eq!(a.by_ref(), (&mut 3, &mut 3, &mut 3, ...));
99            /// ```
100            fn by_ref_mut(&mut self) -> ($(&mut Self::$item, )*);
101
102            /// Takes `&(a, a, a, ...)` and returns `(a, a, a, ...)` 
103            /// # Examples
104            /// ```ignore
105            /// let a = (3, 3, 3, ..,);
106            /// assert_eq!(a, a.clone());
107            /// ```
108            fn cloned(&self) -> ($(Self::$item, )*)
109            where
110                Self::Item: Clone
111            {
112                self.by_ref().map(|x| x.clone())
113            }
114
115            /// Find the leftest element which satisfies `f` and returns it.
116            /// # Example
117            /// ```ignore
118            /// let mut a = (3, 3, 5, 3, ...);
119            /// if let Some(x) = a.by_ref_mut().find(|&&mut x| x == 5) {
120            ///     *x = 3
121            /// }
122            /// assert!(a.same());
123            /// ```
124            fn find<F>(self, f: F) -> Option<Self::Item>
125            where
126                F: FnMut(&Self::Item) -> bool;
127
128            /// Takes a closure `f` and applies it to all elements to tuple, and produce single value.
129            /// This is similar to [`std::iter::Iterator::fold`](https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.fold)
130            /// # Example
131            /// ```ignore
132            /// let a = (3, 4, 5, ...)
133            /// let sum = a.fold(0, |sum, x| sum + x);
134            /// ```
135            fn fold<B, F>(self, init: B, f: F) -> B
136            where
137                F: FnMut(B, Self::Item) -> B;
138
139            /// Takes a closure `f` and applies it to all elements to tuple.
140            /// `f` can cause side effect(because it's `FnMut`), but this method return nothing.
141            /// Similar to [`std::iter::Iterator::for_each`](https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.for_each)
142            /// # Example
143            /// ```ignore
144            /// let a = (3, 4, 5, ...);
145            /// let mut sum = 0;
146            /// a.for_each(|x| sum += x);
147            /// ```
148            fn for_each<F>(self, f: F)
149            where
150                F: FnMut(Self::Item) -> ();
151
152            /// return Self.
153            /// It's not intended to used by user.
154            fn id(self) -> ($(Self::$item,)*);
155            
156            /// Convert tuple into Vec.
157            /// # Example
158            /// ```ignore
159            /// let a = (3, 4, 5, ...)
160            /// assert_eq(a.into_vec(), vec![3, 4, 5, ...])
161            /// ```
162            fn into_vec(self) -> Vec<Self::Item>;
163
164            /// Takes a closure `f` and (a, a, a, ...), then returns (f(a), f(a), f(a), ...).
165            /// Similar to [`std::iter::Iterator::map`](https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.map).
166            /// # Example
167            /// ```ignore
168            /// let a = (3, 4, 5, ...);
169            /// assert_eq!(a.map(|x| x * 2), (6, 8, 10, ...));
170            /// ```
171            fn map<B, F>(self, f: F) -> ($($other, )*)
172            where
173                F: FnMut(Self::Item) -> B;
174
175            /// return nth element in the tuple.
176            /// # Example
177            /// ```ignore
178            /// let a = (3, 4, 5, ..);
179            /// assert_eq!(a.nth(2), Some(5));
180            /// ```
181            fn nth(self, i: usize) -> Option<Self::Item>;
182
183            /// Checks if all elements of the tuple is same.
184            /// # Example
185            /// ```ignore
186            /// let a = (3, 3, 3, ...);
187            /// assert!(a.same());
188            /// ```
189            fn same(self) -> bool
190            where
191                Self::Item: PartialEq;
192
193            /// Takes i and checks if all elements of the tuple is same as i.
194            /// # Example
195            /// ```ignore
196            /// let a = (3, 3, 3, ...);
197            /// assert!(a.same_as(3));
198            /// ```
199            fn same_as(self, i: Self::Item) -> bool
200            where
201                Self::Item: PartialEq;
202
203            /// Takes `(a, b, c, ...)` then returns `a + b + c ...`
204            fn sum(self) -> Self::Item
205            where
206                 Self::Item: ::std::ops::AddAssign;
207
208            /// Takes `(a, b, c, ...)` then returns `a + b + c ...`
209            fn product(self) -> Self::Item
210            where
211                 Self::Item: ::std::ops::MulAssign;
212
213            /// Takes `(a, b, c, ...)` then returns the maximum value of tuple.
214            /// This method is named `tmax` instead of `max`, to avoid overlap
215            /// to `std::cmp::ord::max`.
216            fn tmax(self) -> Self::Item
217            where
218                Self::Item: ::std::cmp::PartialOrd;
219
220            /// Takes `(a, b, c, ...)` then returns the minimum value of tuple.
221            /// This method is named `tmin` instead of `min`, to avoid overlap
222            /// to `std::cmp::ord::min`.
223            fn tmin(self) -> Self::Item
224            where
225                Self::Item: ::std::cmp::PartialOrd;
226            
227            /// Takes `(a, a, a, ...)` and `(b, b, b, ...)` then returns `((a, b), (a, b), (a, b), ...)` 
228            /// # Example
229            /// ```ignore
230            /// let a = (3, 4, 5, ...);
231            /// let b = ('a', 'b', 'c', ...);
232            /// assert_eq!(a.zip(b), ((3, 'a'), (4, 'b'), (5, 'c'), ...));
233            /// ```
234            fn zip<U, B>(self, other: U) -> ($((Self::$item, $other),)*)
235            where
236                U: $trait<Item = B>;
237
238            /// Takes `(a, a, a, ...)` and `(b, b, b, ...)` and closure f,
239            /// then returns `(f(a, b), f(a, b), f(a, b), ...)` 
240            /// # Example
241            /// ```ignore
242            /// let a = (3, 4, 5, ...);
243            /// let b = ('a', 'b', 'c', ...);
244            /// assert_eq!(
245            ///     a.zipf(b, |x, y| format!("{}{}", x, y)),
246            ///     ("3a", "4b", "5c", ...).map(|x| x.to_owned())
247            /// );
248            /// ```
249            fn zipf<U, I, F, B>(self, other: U, f: F) -> ($($other,)*)
250            where
251                U: $trait<Item = I>,
252                F: FnMut(Self::Item, I) -> B;
253
254            /// Takes `(a, a, a, ...)` and `(b, b, b, ...)`,
255            /// then returns `(a + b, a + b, a + b, ...)` 
256            /// # Example
257            /// ```ignore
258            /// let a = (3, 4, 5, ...);
259            /// let b = (7, 8, 9, ....)
260            /// assert_eq!(a.add(b), (10, 12, 14, ...));
261            /// ```
262            fn add<U, I, B>(self, other: U) -> ($($other,)*)
263            where
264                U: $trait<Item = I>,
265                Self::Item: ::std::ops::Add<I, Output = B>,
266                Self: Sized,
267            {
268                self.zipf(other, |a, b| a + b)
269            }
270
271            /// Takes `(a, a, a, ...)` and `(b, b, b, ...)`,
272            /// then returns `(a - b, a - b, a - b, ...)` 
273            /// # Example
274            /// ```ignore
275            /// let a = (7, 8, 9, ....);
276            /// let b = (3, 4, 5, ....);
277            /// assert!(a.sub(b).same());
278            /// ```
279            fn sub<U, I, B>(self, other: U) -> ($($other,)*)
280            where
281                U: $trait<Item = I>,
282                Self::Item: ::std::ops::Sub<I, Output = B>,
283                Self: Sized,
284            {
285                self.zipf(other, |a, b| a - b)
286            }
287
288            /// Takes `(a, a, a, ...)` and `(b, b, b, ...)`,
289            /// then returns `(a * b, a * b, a * b, ...)` 
290            /// # Example
291            /// ```ignore
292            /// let a = (7, 8, 9, ....);
293            /// let b = (3, 4, 5, ....);
294            /// assert_eq!(a.mul(b), (21, 32, 45, ...));
295            /// ```
296            fn mul<U, I, B>(self, other: U) -> ($($other,)*)
297            where
298                U: $trait<Item = I>,
299                Self::Item: ::std::ops::Mul<I, Output = B>,
300                Self: Sized,
301            {
302                self.zipf(other, |a, b| a * b)
303            }
304
305            /// Takes `(a, a, a, ...)` and `(b, b, b, ...)`,
306            /// then returns `(a * b, a * b, a * b, ...)` 
307            /// # Example
308            /// ```ignore
309            /// let a = (6, 8, 10, ....);
310            /// let b = (3, 4, 5, ....);
311            /// assert!(a.div(b).same());
312            /// ```
313            fn div<U, I, B>(self, other: U) -> ($($other,)*)
314            where
315                U: $trait<Item = I>,
316                Self::Item: ::std::ops::Div<I, Output = B>,
317                Self: Sized,
318            {
319                self.zipf(other, |a, b| a / b)
320            }
321        }
322        
323        impl<T> $trait for ($($self, )*) {
324            type Item = T;
325
326            fn any<F>(self, mut f: F) -> bool
327            where
328                F: FnMut(Self::Item) -> bool
329            {
330                let ($($name,)*) = self;
331                $(if f($name) { return true } )*
332                false
333            }
334            
335            fn all<F>(self, mut f: F) -> bool
336            where
337                F: FnMut(Self::Item) -> bool
338            {
339                let ($($name,)*) = self;
340                $(if !f($name) { return false } )*
341                true
342            }
343
344            fn by_ref(&self) -> ($(&Self::$item, )*) {
345                let ($(ref $name,)*) = *self;
346                ($($name,)*)
347            }
348
349            fn by_ref_mut(&mut self) -> ($(&mut Self::$item, )*) {
350                let ($(ref mut $name,)*) = *self;
351                ($($name,)*)
352            }
353
354            fn find<F>(self, mut f: F) -> Option<Self::Item>
355            where
356                F: FnMut(&Self::Item) -> bool
357            {
358                let ($($name,)*) = self;
359                $(if f(&$name) { return Some($name) })*
360                None
361            }
362            
363            fn fold<B, F>(self, mut init: B, mut f: F) -> B
364            where
365                F: FnMut(B, Self::Item) -> B
366            {
367                let ($($name,)*) = self;
368                $(init = f(init, $name);)*
369                init
370            }
371            
372            fn for_each<F>(self, mut f: F)
373            where
374                F: FnMut(Self::Item) -> ()
375            {
376                let ($($name,)*) = self;
377                $(f($name);)*
378            }
379
380            fn id(self) -> ($(Self::$item,)*) {
381                let ($($name,)*) = self;
382                ($($name,)*)
383            }
384            
385            fn into_vec(self) -> Vec<Self::Item> {
386                let ($($name,)*) = self;
387                let mut v = Vec::new();
388                $(v.push($name);)*
389                v
390            }
391
392
393            fn nth(self, i: usize) -> Option<Self::Item> {
394                let ($($name,)*) = self;
395                let mut _cnt = 0;
396                $(if _cnt == i { return Some($name) } else { _cnt += 1 })*
397                None
398            }
399            
400            fn map<B, F>(self, mut f: F) -> ($($other, )*)
401            where
402                F: FnMut(Self::Item) -> B
403            {
404                let ($($name,)*) = self;
405                ($(f($name),)*)
406            }
407
408            #[allow(unused_variables)]
409            fn same(self) -> bool
410            where
411                Self::Item: PartialEq
412            {
413                let (first, $($name_reduced,)*) = self;
414                $(if $name_reduced != first { return false } )*
415                true
416            }
417
418            fn same_as(self, i: Self::Item) -> bool
419            where
420                Self::Item: PartialEq
421            {
422                let ($($name,)*) = self;
423                $(if $name != i { return false })*
424                true
425            }
426
427            #[allow(unused_mut)]
428            fn sum(self) -> Self::Item
429            where
430                Self::Item: ::std::ops::AddAssign
431            {
432                let (mut acc, $($name_reduced,)*) = self;
433                $(acc += $name_reduced;)*
434                acc
435            }
436
437            #[allow(unused_mut)]
438            fn product(self) -> Self::Item
439            where
440                Self::Item: ::std::ops::MulAssign
441            {
442                let (mut acc, $($name_reduced,)*) = self;
443                $(acc *= $name_reduced;)*
444                acc
445            }
446
447            #[allow(unused_mut)]
448            fn tmax(self) -> Self::Item
449            where
450                Self::Item: ::std::cmp::PartialOrd
451            {
452                let (mut acc, $($name_reduced,)*) = self;
453                $(if acc < $name_reduced {
454                    acc = $name_reduced;
455                })*
456                acc
457            }
458
459            #[allow(unused_mut)]
460            fn tmin(self) -> Self::Item
461            where
462                Self::Item: ::std::cmp::PartialOrd
463            {
464                let (mut acc, $($name_reduced,)*) = self;
465                $(if acc > $name_reduced {
466                    acc = $name_reduced;
467                })*
468                acc
469            }
470
471            fn zip<U, B>(self, other: U) -> ($((Self::$item, $other),)*)
472            where
473                U: $trait<Item = B>
474            {
475                let ($($name,)*) = self;
476                let ($($name2,)*) = other.id();
477                ($(($name, $name2),)*)
478            }
479
480            fn zipf<U, I, F, B>(self, other: U, mut f: F) -> ($($other,)*)
481            where
482                U: $trait<Item = I>,
483                F: FnMut(Self::Item, I) -> B
484            {
485                let ($($name,)*) = self;
486                let ($($name2,)*) = other.id();
487                ($(f($name, $name2),)*)
488            }
489        }
490    };
491}
492
493impl_tuple_map!{
494    TupleMap1,
495    ,
496    a,
497    a2,
498    Item,
499    T,
500    B
501}
502impl_tuple_map!{
503    TupleMap2,
504    b,
505    a b,
506    a2 b2,
507    Item Item,
508    T T,
509    B B
510}
511impl_tuple_map!{
512    TupleMap3,
513    b c,
514    a b c,
515    a2 b2 c2,
516    Item Item Item,
517    T T T,
518    B B B
519}
520impl_tuple_map!{
521    TupleMap4,
522    b c d,
523    a b c d,
524    a2 b2 c2 d2,
525    Item Item Item Item,
526    T T T T,
527    B B B B
528}
529impl_tuple_map!{
530    TupleMap5,
531    b c d e,
532    a b c d e,
533    a2 b2 c2 d2 e2,
534    Item Item Item Item Item,
535    T T T T T,
536    B B B B B
537}
538impl_tuple_map!{
539    TupleMap6,
540    b c d e f,
541    a b c d e f,
542    a2 b2 c2 d2 e2 f2,
543    Item Item Item Item Item Item,
544    T T T T T T,
545    B B B B B B
546}
547impl_tuple_map!{
548    TupleMap7,
549    b c d e f g,
550    a b c d e f g,
551    a2 b2 c2 d2 e2 f2 g2,
552    Item Item Item Item Item Item Item,
553    T T T T T T T,
554    B B B B B B B
555}
556impl_tuple_map!{
557    TupleMap8,
558    b c d e f g h,
559    a b c d e f g h,
560    a2 b2 c2 d2 e2 f2 g2 h2,
561    Item Item Item Item Item Item Item Item,
562    T T T T T T T T,
563    B B B B B B B B
564}
565impl_tuple_map!{
566    TupleMap9,
567    b c d e f g h i,
568    a b c d e f g h i,
569    a2 b2 c2 d2 e2 f2 g2 h2 i2,
570    Item Item Item Item Item Item Item Item Item,
571    T T T T T T T T T,
572    B B B B B B B B B
573}
574impl_tuple_map!{
575    TupleMap10,
576    b c d e f g h i j,
577    a b c d e f g h i j,
578    a2 b2 c2 d2 e2 f2 g2 h2 i2 j2,
579    Item Item Item Item Item Item Item Item Item Item,
580    T T T T T T T T T T,
581    B B B B B B B B B B
582}
583impl_tuple_map!{
584    TupleMap11,
585    b c d e f g h i j k,
586    a b c d e f g h i j k,
587    a2 b2 c2 d2 e2 f2 g2 h2 i2 j2 k2,
588    Item Item Item Item Item Item Item Item Item Item Item,
589    T T T T T T T T T T T,
590    B B B B B B B B B B B
591}
592impl_tuple_map!{
593    TupleMap12,
594    b c d e f g h i j k l,
595    a b c d e f g h i j k l,
596    a2 b2 c2 d2 e2 f2 g2 h2 i2 j2 k2 l2,
597    Item Item Item Item Item Item Item Item Item Item Item Item,
598    T T T T T T T T T T T T,
599    B B B B B B B B B B B B
600}
601impl_tuple_map!{
602    TupleMap13,
603    b c d e f g h i j k l m,
604    a b c d e f g h i j k l m,
605    a2 b2 c2 d2 e2 f2 g2 h2 i2 j2 k2 l2 m2,
606    Item Item Item Item Item Item Item Item Item Item Item Item Item,
607    T T T T T T T T T T T T T,
608    B B B B B B B B B B B B B
609}
610impl_tuple_map!{
611    TupleMap14,
612    b c d e f g h i j k l m n,
613    a b c d e f g h i j k l m n,
614    a2 b2 c2 d2 e2 f2 g2 h2 i2 j2 k2 l2 m2 n2,
615    Item Item Item Item Item Item Item Item Item Item Item Item Item Item,
616    T T T T T T T T T T T T T T,
617    B B B B B B B B B B B B B B
618}
619impl_tuple_map!{
620    TupleMap15,
621    b c d e f g h i j k l m n o,
622    a b c d e f g h i j k l m n o,
623    a2 b2 c2 d2 e2 f2 g2 h2 i2 j2 k2 l2 m2 n2 o2,
624    Item Item Item Item Item Item Item Item Item Item Item Item Item Item Item,
625    T T T T T T T T T T T T T T T,
626    B B B B B B B B B B B B B B B
627}
628impl_tuple_map!{
629    TupleMap16,
630    b c d e f g h i j k l m n o p,
631    a b c d e f g h i j k l m n o p,
632    a2 b2 c2 d2 e2 f2 g2 h2 i2 j2 k2 l2 m2 n2 o2 p2,
633    Item Item Item Item Item Item Item Item Item Item Item Item Item Item Item Item,
634    T T T T T T T T T T T T T T T T,
635    B B B B B B B B B B B B B B B B
636}
637
638#[cfg(test)]
639mod tests {
640    use super::*;
641
642    #[test]
643    fn test_all() {
644        let a = (3, 9, 12, 15);
645        assert!(a.all(|x| x % 3 == 0));
646        assert!(!a.all(|x| x % 4 == 0));
647    }
648
649    #[test]
650    fn test_any() {
651        let a = (3, 9, 12, 15);
652        assert!(a.any(|x| x % 4 == 0));
653        assert!(!a.any(|x| x % 7 == 0));
654    }
655
656    #[test]
657    fn test_by_ref() {
658        let a = (3, 3, 3);
659        let b = a.by_ref();
660        assert_eq!(b, (&3, &3, &3))
661    }
662
663    #[test]
664    fn test_by_ref_mut() {
665        let mut a = (3, 3, 3);
666        assert_eq!(a.by_ref_mut(), (&mut 3, &mut 3, &mut 3));
667        a.by_ref_mut().for_each(|x| *x += 5);
668        assert_eq!(a, (8, 8, 8))
669    }
670
671    #[test]
672    fn test_cloned() {
673        let mut a = (3, 3, 3);
674        assert_eq!(a, a.cloned());
675        let b = a.cloned().map(|x| x * 3);
676        a.by_ref_mut().for_each(|x| *x *= 3);
677        assert_eq!(b, a.cloned())
678    }
679
680    #[test]
681    fn test_find() {
682        let mut a = (3, 3, 5, 3);
683        if let Some(x) = a.by_ref_mut().find(|&&mut x| x == 5) {
684            *x = 3
685        }
686        assert!(a.same());
687    }
688
689    #[test]
690    fn test_fold() {
691        let a = (3, 3, 3, 3);
692        let sum = a.fold(0, |sum, x| sum + x);
693        assert_eq!(sum, 12)
694    }
695
696    #[test]
697    fn test_into_vec() {
698        assert_eq!((3, 3, 3).into_vec(), vec![3, 3, 3]);
699    }
700
701    #[test]
702    fn test_map() {
703        let a = (3, 3, 3);
704        let mut cnt = 0;
705        let b = a.map(|x| {
706            cnt += 1;
707            x + cnt
708        });
709        assert_eq!(b, (4, 5, 6))
710    }
711
712    #[test]
713    fn test_nth() {
714        let a = (3, 4, 5, 6);
715        assert_eq!(a.nth(2), Some(5));
716    }
717
718    #[test]
719    fn test_same() {
720        let a = (3, 3, 3);
721        assert!(a.same());
722    }
723
724    #[test]
725    fn test_same_as() {
726        let a = (3, 3, 3);
727        assert!(a.same_as(3));
728    }
729
730    #[test]
731    fn test_zip() {
732        let a = (1, 2, 3);
733        let b = ("a", "b", "c");
734        assert_eq!(a.zip(b), ((1, "a"), (2, "b"), (3, "c")));
735    }
736
737    #[test]
738    fn test_zipf() {
739        let a = (1, 2, 3);
740        let b = ("a", "b", "c");
741        assert_eq!(
742            a.zipf(b, |x, y| format!("{}{}", x, y)),
743            ("1a", "2b", "3c").map(|x| x.to_owned())
744        );
745    }
746
747    #[test]
748    fn test_add() {
749        let a = (3, 4, 5);
750        assert_eq!(a.add((3, 4, 5)), (6, 8, 10));
751    }
752
753    #[test]
754    fn test_sub() {
755        let a = (3, 4, 5);
756        assert!(a.sub((1, 2, 3)).same_as(2));
757    }
758
759    #[test]
760    fn test_mul() {
761        let a = (3, 4, 5);
762        assert_eq!(a.mul((1, 2, 3)), (3, 8, 15));
763    }
764
765    #[test]
766    fn test_div() {
767        let a = (6, 8, 10);
768        let b = (3, 4, 5);
769        assert!(a.div(b).same_as(2));
770    }
771
772    #[test]
773    fn test_sum() {
774        let a = (6, 8, 10);
775        assert_eq!(a.sum(), 24);
776    }
777
778    #[test]
779    fn test_prod() {
780        let a = (6, 8, 10);
781        assert_eq!(a.product(), 480);
782    }
783
784    #[test]
785    fn test_tmin() {
786        let a = (6, 8, 10);
787        assert_eq!(a.tmin(), 6);
788    }
789
790    #[test]
791    fn test_tmax() {
792        let a = (6, 8, 10);
793        assert_eq!(a.tmax(), 10);
794    }
795}