1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
use impl_typed_split;
/// ## TypedSplit
///
/// [`TypedSplit`] allows for a tuple to be split given a type patterns. A tuple
/// can be split either specifying the leftmost or rightmost tuple pattern, or by
/// inferring a tuple sequence for extraction, or by explicitly defining the
/// left-exclusive/right-inclusive center bound index `INDEX`.
///
/// [`TypedSplit::split`] consumes `Self` returning the specified elements, borrows
/// `&Self`, returning element references, and mutably borrow `&mut Self` returning
/// mutable element references.
///
/// ```rust
/// # use typed_tuple::TypedSplit;
/// let mut tuple = (0u8, 1u16, 2u32);
/// let (_, last_ref): (_, (&_,)) = (&tuple).split();
/// let (_, last_mut): (_, (&mut _,)) = (&mut tuple).split();
/// let (_, last): (_, (_,)) = tuple.split();
/// ```
///
/// ## Split by type
///
/// An index will be inferred by, at a minimum, specifying the number of elements
/// in either (or both) the left or right segment.
///
/// ```rust
/// # use typed_tuple::TypedSplit;
/// let tuple = (0u8, 1u16, 2u32, 3u64, 4u128);
/// let (left, right): ((_, _, _), _) = tuple.split(); // Split after the first 3 elements.
/// assert_eq!(left, (0, 1, 2));
/// assert_eq!(right, (3, 4));
/// let (left, right): (_, (_,)) = tuple.split(); // Split prior to the last element.
/// assert_eq!(left, (0, 1, 2, 3));
/// assert_eq!(right, (4,));
/// ```
///
/// ## Split by index
///
/// Where a tuple pattern is not inferred, the center bound index `INDEX` must be
/// specified. The given index is representative of the exclusive upper bound of
/// the left segment, and the inclusive lower bound of the right segment (analogous
/// to the indices of split operations in [`core::slice`]).
///
/// ```rust
/// # use typed_tuple::TypedSplit;
/// let tuple = (0u8, 1u16, 2u32, 3u64, 4u128);
/// let (left, right) = TypedSplit::<3, _, _>::split(tuple); // Split at index 3.
/// assert_eq!(left, (0, 1, 2));
/// assert_eq!(right, (3, 4));
/// let (left, right) = TypedSplit::<0, _, _>::split(tuple); // Split at index 0.
/// assert_eq!(left, ());
/// assert_eq!(right, (0, 1, 2, 3, 4));
/// ```
impl_typed_split!;