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}