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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
use PhantomData;
use crateCons;
/// Index value to indicate the target is in the left of a [`Cons`].
/// Index value to indicate that the target is at some other index of a [`Cons`].
;
/// Determine whether a target is located at some index. This trait will be implemented for all
/// types that contain the target type.
///
/// Currently, there is no mechanism to retrieve the target value, only determine if it does exist
/// or not. This allows for using zero-sized types to be used as flags within the type system.
///
/// If `Index` is allowed to be inferred, it's possible to check if some arbitrary value contains
/// `Target` at any location. With very long tuples there is a chance that the type checker will
/// raise a error due to too much recursion, however it should be fine to raise this limit if your
/// needs require it..
///
/// # Examples
///
/// Allowing `Index` to be inferred allows for searching at any depth.
///
/// ```
/// # use tuple_traits::Contains;
/// #
/// struct A;
/// struct B;
/// struct C;
///
/// fn requires_c<T, Index>(value: T)
/// where
/// T: Contains<C, Index>
/// {
/// }
///
/// requires_c((A, B, C));
/// ```
///
/// The trait bound will not be satisfied for any tuples that do not contain the target value.
///
/// ```compile_fail
/// # use tuple_traits::Contains;
/// #
/// # struct A;
/// # struct B;
/// # struct C;
/// #
/// # fn requires_c<T, Index>(value: T)
/// # where
/// # T: Contains<C, Index>
/// # {
/// # }
/// #
/// requires_c((A, B));
/// ```
///
/// The target value can also be a generic on the function without a parameter, however this isn't
/// recommended due to Rust requiring all generics to be listed by the caller.
/// ```
/// # use tuple_traits::Contains;
/// #
/// # struct A;
/// # struct B;
/// # struct C;
/// #
/// fn requires_c<T, Index>()
/// where
/// T: Contains<C, Index>
/// {
/// }
///
/// requires_c::<(A, B, C), _>();
/// ```
///
/// Technique based off of [Lloyd's blog post] on type-level recursion in Rust.
///
/// [Lloyd's blog post]: https://beachape.com/blog/2017/03/12/gentle-intro-to-type-level-recursion-in-Rust-from-zero-to-frunk-hlist-sculpting
/// Base implementation, where the target is on the left of a cons.
/// Recursive implementation, advancing the index to try resolve the trait again.