title: How to implement an introspection of a trait content?
body: <p>I implemented a small library to make calculations step by step by modifying
  plan incrementally. I would like to allow making an introspection of the plans
  without modifying the library itself. For instance I need implementing a
  function which prints next plan after each step of execution. Or I may need to
  convert a plan into another representation.</p>
  <p>The central abstraction of the library is a <code>Plan&lt;T, R&gt;</code> trait which inputs an
  argument <code>T</code> and calculates <code>R</code>:</p>
  <pre><code>pub trait Plan&lt;T, R&gt; {
      fn step(self: Box&lt;Self&gt;, arg: T) -&gt; StepResult&lt;R&gt;;
  }
  </code></pre>
  <p>Plan returns <code>StepResult&lt;R&gt;</code> which is either an immediate result or new plan
  from <code>()</code> to <code>R</code>:</p>
  <pre><code>pub enum StepResult&lt;R&gt; {
      Plan(Box&lt;dyn Plan&lt;(), R&gt;&gt;),
      Result(R),
  }
  </code></pre>
  <p>Finally I have few specific plans, for example these two:</p>
  <pre><code>pub struct OperatorPlan&lt;T, R&gt; {
      operator: Box&lt;dyn FnOnce(T) -&gt; StepResult&lt;R&gt;&gt;,
  }
  
  impl&lt;T, R&gt; Plan&lt;T, R&gt; for OperatorPlan&lt;T, R&gt; {
      fn step(self: Box&lt;Self&gt;, arg: T) -&gt; StepResult&lt;R&gt; {
          (self.operator)(arg)
      }
  }
  
  pub struct SequencePlan&lt;T1, T2, R&gt; {
      first: Box&lt;dyn Plan&lt;T1, T2&gt;&gt;,
      second: Box&lt;dyn Plan&lt;T2, R&gt;&gt;,
  }
  
  impl&lt;T1: 'static, T2: 'static, R: 'static&gt; Plan&lt;T1, R&gt; for SequencePlan&lt;T1, T2, R&gt; {
      fn step(self: Box&lt;Self&gt;, arg: T1) -&gt; StepResult&lt;R&gt; {
          match self.first.step(arg) {
              StepResult::Plan(next) =&gt; StepResult::plan(SequencePlan{
                  first: next,
                  second: self.second,
              }),
              StepResult::Result(result) =&gt; StepResult::plan(ApplyPlan{
                  arg: result,
                  plan: self.second,
              }),
          }
      }
  }
  </code></pre>
  <p>Using the plans I can combine operators and calculate <code>R</code> from <code>T</code> step by step
  building a plan incrementally.</p>
  <p>I have read answers to <a href="https://stackoverflow.com/questions/27957103/how-do-i-create-a-heterogeneous-collection-of-objects">How do I create a heterogeneous collection of
  objects?</a>
  But both &quot;trait&quot; and &quot;enum&quot; solutions doesn't work to me.</p>
  <p>I could add new function like <code>fmt</code> or <code>convert</code> into <code>Plan&lt;T, R&gt;</code> trait each
  time but the goal is to provide a single function to allow introspection
  without modifying the library itself.</p>
  <p>I cannot list all plan types as a enum because some of them (like
  <code>SequencePlan</code>) are generics and thus <code>OperatorPlan</code> can return a <code>Plan</code> which
  exact type is not known in advance.</p>
  <p>I tried implementing a Visitor pattern by adding new trait <code>Visitor&lt;T, R&gt;</code> and
  method to accept it into <code>Plan&lt;T, R&gt;</code> trait:</p>
  <pre><code>pub trait Plan&lt;T, R&gt; {
      fn step(self: Box&lt;Self&gt;, arg: T) -&gt; StepResult&lt;R&gt;;
      fn accept(&amp;self, visitor: &amp;Box&lt;dyn PlanVisitor&lt;T, R&gt;&gt;);
  }
  
  trait PlanVisitor&lt;T, R&gt; {
      fn visit_operator(&amp;mut self, plan: &amp;OperatorPlan&lt;T, R&gt;);
      // Compilation error!
      //fn visit_sequence&lt;T2&gt;(&amp;mut self, plan: &amp;SequencePlan&lt;T, T2, R&gt;);
  }
  </code></pre>
  <p>This doesn't compile because function visiting <code>SequencePlan</code> is parameterized
  by additional type. On the other hand I don't need to know the full type of the
  <code>Plan</code> to print it.</p>
  <p>In C++ I could use <code>dynamic_cast&lt;Display&gt;</code> to see if <code>Plan</code> is printable and
  use the pointer to <code>Display</code> interface after. I know that Rust doesn't support
  downcasting out of the box.</p>
  <p>I would like to know what is a natural way to implement such introspection
  in Rust?</p>
  <p>More complete code on <a href="https://play.rust-lang.org/?version=nightly&amp;mode=debug&amp;edition=2015&amp;gist=746fcb0d46150c6bf02c1848403d24ac" rel="nofollow noreferrer">playground</a></p>