liter/meta/
tuple.rs

1use liter_derive::impl_tuple;
2
3pub use marker::Marker;
4
5pub mod marker {
6	pub struct One;
7	pub struct Many;
8
9	pub trait Marker: private::Sealed {}
10	impl Marker for One {}
11	impl Marker for Many {}
12	mod private {
13		pub trait Sealed {}
14		impl Sealed for super::One {}
15		impl Sealed for super::Many {}
16	}
17}
18
19pub trait Tuple<M: Marker>: private::Sealed<M> {
20	type Ref<'l> where Self: 'l;
21	type Mut<'l> where Self: 'l;
22	fn take_ref(&self) -> Self::Ref<'_>;
23}
24
25pub trait CloneFromRef<M: Marker>: Tuple<M> {
26	fn clone_from_ref(from: Self::Ref<'_>) -> Self;
27}
28
29mod private {
30	use super::*;
31	pub trait Sealed<M> {}
32	impl<T> Sealed<marker::One> for T {}
33	#[impl_tuple(2..=16)]
34	impl Sealed<marker::Many> for Each!(T) {}
35}
36
37impl<T> Tuple<marker::One> for T {
38	type Ref<'l> = &'l T where Self: 'l;
39	type Mut<'l> = &'l mut T where Self: 'l;
40	fn take_ref(&self) -> Self::Ref<'_> {self}
41}
42
43#[impl_tuple(2..=16)]
44impl Tuple<marker::Many> for Each!(T) {
45	type Ref<'l> = Each!(T => &'l T) where Self: 'l;
46	type Mut<'l> = Each!(T => &'l mut T) where Self: 'l;
47
48	/// `&(A, B, C)` → `(&A, &B, &C)`
49	fn take_ref(&self) -> Self::Ref<'_> {
50		each!{ref field => field}
51	}
52}
53
54impl<T: 'static> CloneFromRef<marker::One> for T
55	where T: for<'x> Tuple<marker::One, Ref<'x> = &'x T> + Clone
56{
57	fn clone_from_ref(from: Self::Ref<'_>) -> Self where Self: 'static {
58		from.clone()
59	}
60}
61
62#[impl_tuple(2..=16)]
63impl CloneFromRef<marker::Many> for Each!(T)
64	where Self: for<'x> Tuple<marker::Many, Ref<'x> = Each!(T => &'x T)>,
65		Every!(T => T: 'static + Clone): '_
66{
67	fn clone_from_ref(from: Self::Ref<'_>) -> Self where Self: 'static {
68		each!(@from, thing => thing.clone())
69	}
70}