Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- use std::marker::PhantomData;
- use std::fmt::Debug;
- enum Z {}
- struct S<N>(PhantomData<N>);
- trait At<N> {
- type Type: ?Sized;
- fn at(&self) -> &Self::Type;
- }
- impl<H, T> At<Z> for (H, T) {
- type Type = H;
- fn at(&self) -> &H { &self.0 }
- }
- impl<H, T, Y, N> At<S<N>> for (H, T)
- where T: At<N, Type=Y>
- {
- type Type = Y;
- fn at(&self) -> &Y {
- self.1.at()
- }
- }
- trait ListPushBack<V> {
- type Output;
- fn push_back(self, value: V) -> Self::Output;
- }
- impl<V> ListPushBack<V> for () {
- type Output = (V, ());
- fn push_back(self, value: V) -> (V, ()) {
- (value, ())
- }
- }
- impl<V, H, T> ListPushBack<V> for (H, T)
- where T: ListPushBack<V>
- {
- type Output = (H, T::Output);
- fn push_back(self, value: V) -> (H, T::Output) {
- (self.0, self.1.push_back(value))
- }
- }
- trait UsefulTrait {
- type Requires;
- fn supply(&self, data: &Self::Requires);
- }
- trait SomeUsefulTrait<A> {
- fn supply(&self, data: &A);
- }
- struct Peeker<T, N>(T, PhantomData<N>);
- impl<T, N, A> SomeUsefulTrait<A> for Peeker<T, N>
- where T: UsefulTrait,
- A: At<N, Type=T::Requires>
- {
- fn supply(&self, data: &A) {
- self.0.supply(data.at())
- }
- }
- trait IntoPeeker<A, N>: UsefulTrait + Sized where Peeker<Self, N>: SomeUsefulTrait<A> {
- fn into_peeker(self) -> Peeker<Self, N>;
- }
- impl<A, N, T> IntoPeeker<A, N> for T
- where T: UsefulTrait,
- A: At<N, Type=T::Requires>
- {
- fn into_peeker(self) -> Peeker<T, N> {
- Peeker(self, PhantomData)
- }
- }
- trait IntoPeekers<A, N> {
- fn into_peekers(self, peekers: &mut Vec<Box<SomeUsefulTrait<A>>>);
- }
- impl<A, N> IntoPeekers<A, N> for () {
- fn into_peekers(self, peekers: &mut Vec<Box<SomeUsefulTrait<A>>>) {}
- }
- impl<A, H: 'static, T, N: 'static> IntoPeekers<A, N> for (H, T)
- where H: IntoPeeker<A, N>,
- T: IntoPeekers<A, S<N>>,
- A: At<N, Type=H::Requires>
- {
- fn into_peekers(self, peekers: &mut Vec<Box<SomeUsefulTrait<A>>>) {
- let (h, t) = self;
- peekers.push(Box::new(h.into_peeker()));
- t.into_peekers(peekers);
- }
- }
- trait UsefulTraitList {
- type AllRequirements;
- }
- impl UsefulTraitList for () {
- type AllRequirements = ();
- }
- impl<H, T> UsefulTraitList for (H, T)
- where H: UsefulTrait,
- T: UsefulTraitList
- {
- type AllRequirements = (H::Requires, T::AllRequirements);
- }
- struct Builder<L> {
- list: L
- }
- impl Builder<()> {
- fn new() -> Builder<()> {
- Builder { list: () }
- }
- }
- impl<L> Builder<L> {
- fn with<T: UsefulTrait>(self, value: T) -> Builder<L::Output> where L: ListPushBack<T> {
- Builder {
- list: self.list.push_back(value)
- }
- }
- }
- impl<L, A> Builder<L>
- where L: UsefulTraitList<AllRequirements=A>
- {
- fn finish(self) -> Engine<L::AllRequirements> where L: IntoPeekers<A, Z> {
- let mut peekers = Vec::new();
- self.list.into_peekers(&mut peekers);
- Engine {
- list: peekers
- }
- }
- }
- struct Engine<A> {
- list: Vec<Box<SomeUsefulTrait<A>>>
- }
- impl<A> Engine<A> {
- fn run(&self, data: &A) {
- for ut in self.list.iter() {
- ut.supply(data);
- }
- }
- }
- struct DataDebugPrinter<D>(PhantomData<D>);
- impl<D: Debug> DataDebugPrinter<D> {
- fn new() -> Self { DataDebugPrinter(PhantomData) }
- }
- impl<D: Debug> UsefulTrait for DataDebugPrinter<D> {
- type Requires = D;
- fn supply(&self, data: &D) {
- println!("{:?}", data);
- }
- }
- fn main() {
- let engine = Builder::new()
- .with(DataDebugPrinter::<i32>::new())
- .with(DataDebugPrinter::<f32>::new())
- .with(DataDebugPrinter::<&'static str>::new())
- .finish();
- engine.run(&(4, (1f32, ("qwe", ()))));
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement