Advertisement
NLinker

DataDebugPrinter

Aug 10th, 2017
226
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 3.83 KB | None | 0 0
  1. use std::marker::PhantomData;
  2. use std::fmt::Debug;
  3.  
  4. enum Z {}
  5. struct S<N>(PhantomData<N>);
  6.  
  7. trait At<N> {
  8.     type Type: ?Sized;
  9.     fn at(&self) -> &Self::Type;
  10. }
  11.  
  12. impl<H, T> At<Z> for (H, T) {
  13.     type Type = H;
  14.     fn at(&self) -> &H { &self.0 }
  15. }
  16.  
  17. impl<H, T, Y, N> At<S<N>> for (H, T)
  18.     where T: At<N, Type=Y>
  19. {
  20.     type Type = Y;
  21.     fn at(&self) -> &Y {
  22.         self.1.at()
  23.     }
  24. }
  25.  
  26.  
  27.  
  28. trait ListPushBack<V> {
  29.     type Output;
  30.     fn push_back(self, value: V) -> Self::Output;
  31. }
  32.  
  33. impl<V> ListPushBack<V> for () {
  34.     type Output = (V, ());
  35.     fn push_back(self, value: V) -> (V, ()) {
  36.         (value, ())
  37.     }
  38. }
  39.  
  40. impl<V, H, T> ListPushBack<V> for (H, T)
  41.     where T: ListPushBack<V>
  42. {
  43.     type Output = (H, T::Output);
  44.     fn push_back(self, value: V) -> (H, T::Output) {
  45.         (self.0, self.1.push_back(value))
  46.     }
  47. }
  48.  
  49. trait UsefulTrait {
  50.     type Requires;
  51.     fn supply(&self, data: &Self::Requires);
  52. }
  53.  
  54. trait SomeUsefulTrait<A> {
  55.     fn supply(&self, data: &A);
  56. }
  57.  
  58. struct Peeker<T, N>(T, PhantomData<N>);
  59. impl<T, N, A> SomeUsefulTrait<A> for Peeker<T, N>
  60.     where T: UsefulTrait,
  61.           A: At<N, Type=T::Requires>
  62. {
  63.     fn supply(&self, data: &A) {
  64.         self.0.supply(data.at())
  65.     }
  66. }
  67.  
  68. trait IntoPeeker<A, N>: UsefulTrait + Sized where Peeker<Self, N>: SomeUsefulTrait<A> {
  69.     fn into_peeker(self) -> Peeker<Self, N>;
  70. }
  71. impl<A, N, T> IntoPeeker<A, N> for T
  72.     where T: UsefulTrait,
  73.           A: At<N, Type=T::Requires>
  74. {
  75.     fn into_peeker(self) -> Peeker<T, N> {
  76.         Peeker(self, PhantomData)
  77.     }
  78. }
  79.  
  80. trait IntoPeekers<A, N> {
  81.     fn into_peekers(self, peekers: &mut Vec<Box<SomeUsefulTrait<A>>>);
  82. }
  83.  
  84. impl<A, N> IntoPeekers<A, N> for () {
  85.     fn into_peekers(self, peekers: &mut Vec<Box<SomeUsefulTrait<A>>>) {}
  86. }
  87.  
  88. impl<A, H: 'static, T, N: 'static> IntoPeekers<A, N> for (H, T)
  89.     where H: IntoPeeker<A, N>,
  90.           T: IntoPeekers<A, S<N>>,
  91.           A: At<N, Type=H::Requires>
  92. {
  93.     fn into_peekers(self, peekers: &mut Vec<Box<SomeUsefulTrait<A>>>) {
  94.         let (h, t) = self;
  95.         peekers.push(Box::new(h.into_peeker()));
  96.         t.into_peekers(peekers);
  97.     }
  98. }
  99.  
  100. trait UsefulTraitList {
  101.     type AllRequirements;
  102. }
  103.  
  104. impl UsefulTraitList for () {
  105.     type AllRequirements = ();
  106. }
  107.  
  108. impl<H, T> UsefulTraitList for (H, T)
  109.     where H: UsefulTrait,
  110.           T: UsefulTraitList
  111. {
  112.     type AllRequirements = (H::Requires, T::AllRequirements);
  113. }
  114.  
  115. struct Builder<L> {
  116.     list: L
  117. }
  118.  
  119. impl Builder<()> {
  120.     fn new() -> Builder<()> {
  121.         Builder { list: () }
  122.     }
  123. }
  124.  
  125. impl<L> Builder<L> {
  126.     fn with<T: UsefulTrait>(self, value: T) -> Builder<L::Output> where L: ListPushBack<T> {
  127.         Builder {
  128.             list: self.list.push_back(value)
  129.         }
  130.     }
  131. }
  132.  
  133. impl<L, A> Builder<L>
  134.     where L: UsefulTraitList<AllRequirements=A>
  135. {
  136.     fn finish(self) -> Engine<L::AllRequirements> where L: IntoPeekers<A, Z> {
  137.         let mut peekers = Vec::new();
  138.         self.list.into_peekers(&mut peekers);
  139.         Engine {
  140.             list: peekers
  141.         }
  142.     }
  143. }
  144.  
  145. struct Engine<A> {
  146.     list: Vec<Box<SomeUsefulTrait<A>>>
  147. }
  148.  
  149. impl<A> Engine<A> {
  150.     fn run(&self, data: &A) {
  151.         for ut in self.list.iter() {
  152.             ut.supply(data);
  153.         }
  154.     }
  155. }
  156.  
  157. struct DataDebugPrinter<D>(PhantomData<D>);
  158. impl<D: Debug> DataDebugPrinter<D> {
  159.     fn new() -> Self { DataDebugPrinter(PhantomData) }
  160. }
  161.  
  162. impl<D: Debug> UsefulTrait for DataDebugPrinter<D> {
  163.     type Requires = D;
  164.     fn supply(&self, data: &D) {
  165.         println!("{:?}", data);
  166.     }
  167. }
  168.  
  169.  
  170. fn main() {
  171.     let engine = Builder::new()
  172.         .with(DataDebugPrinter::<i32>::new())
  173.         .with(DataDebugPrinter::<f32>::new())
  174.         .with(DataDebugPrinter::<&'static str>::new())
  175.        .finish();
  176.  
  177.    engine.run(&(4, (1f32, ("qwe", ()))));
  178. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement