title: How to use Read::take recursively to read a tree structures with a generic Read trait?
body: <p>When storing tree structures in binary files its fairly common to store a sequence of <em>chunks</em>, each containing:  <code>[type_id, size, ... ]</code> and optionally nested child chunks.</p>
  
  <p>This allows readers to read in the tree, skipping types that aren't recognized since their size is known.</p>
  
  <p>See: <a href="http://www.fileformat.info/format/iff/egff.htm" rel="nofollow noreferrer">Amiga IFF as an example of this</a>.</p>
  
  <p>When writing readers for this kind of data, its important to make sure each level of the recursion reads exactly the number of bytes defined by its chunk size.</p>
  
  <p>Even using the <code>Seek</code> trait, while it allows skipping to the next chunk, it doesn't ensure nested functions aren't reading past their bounds.</p>
  
  <p>So its useful that reading past the pre-defined chunk size will cause an EOF.</p>
  
  <p>Is there a way to use <a href="https://doc.rust-lang.org/nightly/std/io/trait.Read.html#method.take" rel="nofollow noreferrer"><code>Read::take</code></a> to get a part of the file sized to the chunk, then read from it in a recursive function?</p>
  
  <hr>
  
  <p>In principle this should be possible, however I ran into a problem using take recursively, where I couldn't get generic types working:</p>
  
  <pre><code>error: reached the recursion limit while instantiating `decode_recursive::&lt;&amp;mut std::io::Take&lt;&amp;mut &amp;mut std::io::Take&lt;&amp;mut &amp;mut std::io::Take&lt;&amp;mut &amp;mut std::io::Take&lt;&amp;mut &amp;mut std::io::Take&lt;&amp;mut &amp;mut std::io::Take&lt;&amp;mut &amp;mut std::io::Take&lt;&amp;mut &amp;mut std::io::Take&lt;&amp;mut &amp;mut std::io::Take&lt;&amp;mut &amp;mut std::io::Take&lt;&amp;mut &amp;mut std::io::Take&lt;&amp;mut &amp;mut std::io::Take&lt;&amp;mut &amp;mut std::io::Take&lt;&amp;mut &amp;mut std::io::Take&lt;&amp;mut &amp;mut std::io::Take&lt;&amp;mut &amp;mut std::io::Take&lt;&amp;mut &amp;mut std::io::Take&lt;&amp;mut &amp;mut std::io::Take&lt;&amp;mut &amp;mut std::io::Take&lt;&amp;mut &amp;mut std::io::Take&lt;&amp;mut &amp;mut std::io::Take&lt;&amp;mut &amp;mut std::io::Take&lt;&amp;mut &amp;mut std::io::Take&lt;&amp;mut &amp;mut std::io::Take&lt;&amp;mut &amp;mut std::io::Take&lt;&amp;mut &amp;mut std::io::Take&lt;&amp;mut &amp;mut std::io::Take&lt;&amp;mut &amp;mut std::io::Take&lt;&amp;mut &amp;mut std::io::Take&lt;&amp;mut &amp;mut std::io::Take&lt;&amp;mut &amp;mut std::io::Take&lt;&amp;mut &amp;mut std::io::Take&lt;&amp;mut &amp;mut std::io::Take&lt;&amp;mut &amp;mut std::io::Take&lt;&amp;mut &amp;mut std::io::Take&lt;&amp;mut &amp;mut std::io::Take&lt;&amp;mut &amp;mut std::io::Take&lt;&amp;mut &amp;mut std::io::Take&lt;&amp;mut &amp;mut std::io::Take&lt;&amp;mut &amp;mut std::io::Take&lt;&amp;mut &amp;mut std::io::Take&lt;&amp;mut &amp;mut std::io::Take&lt;&amp;mut &amp;mut std::io::Take&lt;&amp;mut &amp;mut std::io::Take&lt;&amp;mut &amp;mut std::io::Take&lt;&amp;mut &amp;mut std::io::Take&lt;&amp;mut &amp;mut std::io::Take&lt;&amp;mut &amp;mut std::io::Take&lt;&amp;mut &amp;mut std::io::Take&lt;&amp;mut &amp;mut std::io::Take&lt;&amp;mut &amp;mut std::io::Take&lt;&amp;mut &amp;mut std::io::Take&lt;&amp;mut &amp;mut std::io::Take&lt;&amp;mut &amp;mut std::io::Take&lt;&amp;mut &amp;mut std::io::Take&lt;&amp;mut &amp;mut std::io::Take&lt;&amp;mut &amp;mut std::io::Take&lt;&amp;mut &amp;mut std::io::Take&lt;&amp;mut &amp;mut std::io::Take&lt;&amp;mut &amp;mut std::io::Take&lt;&amp;mut &amp;mut std::io::Take&lt;&amp;mut &amp;mut std::io::Take&lt;&amp;mut &amp;mut std::io::Take&lt;&amp;mut &amp;mut std::io::Take&lt;&amp;mut &amp;mut std::io::Take&lt;&amp;mut &amp;[u8]&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;
  </code></pre>
  
  <p>Is it possible to use <code>Read::take</code> in a function to recursively limit the range of data that can be read?</p>
  
  <p>Note that using vector <code>Slice</code> would resolve this but I would like to use the <code>Read</code> trait.</p>
  
  <hr>
  
  <p>Example code which encodes a small tree structure and tries to read it:</p>
  
  <pre><code>use ::std::io;
  
  fn encode_recursive(data: &amp;mut Vec&lt;u8&gt;, chunk_size: u8) {
      let data_len_init = data.len();
      let mut size = chunk_size;
      size -= 2;
      if size &gt; 8 {
          data.push(2); // children
          data.push(size);
          let split = size / 2;
          encode_recursive(data, split);
          encode_recursive(data, size - split);
      } else {
          data.push(0); // no children
          data.push(size);
          for i in 0..size {
              data.push(i); // dummy leaf data
          }
      }
      debug_assert_eq!(data.len(), data_len_init + chunk_size as usize);
  }
  
  fn decode_recursive&lt;R&gt;(mut f: R, depth: usize) -&gt; Result&lt;(), io::Error&gt;
      where R: io::Read,
  {
      let mut chunk_data: [u8; 2] = [0; 2];
      io::Read::read_exact(&amp;mut f, &amp;mut chunk_data)?;
      let children = chunk_data[0];
      let chunk_size = chunk_data[1];
  
      let mut f_sub = io::Read::take(&amp;mut f, chunk_size as u64);
  
      println!("{:indent$}Chunk: {} depth", "", chunk_data[0], indent=depth);
      if children != 0 {
          for _ in 0..children {
              decode_recursive(&amp;mut f_sub, depth + 1)?;
          }
      } else {
          let mut chunk_leaf: [u8; 1] = [0; 1];
          for _ in 0..(chunk_size as usize) {
              io::Read::read_exact(&amp;mut f_sub, &amp;mut chunk_leaf)?;
              print!("{},", chunk_leaf[0]);
          }
          println!();
      }
  
      // read all remaining data in the case recursive functions finish early.
      io::copy(&amp;mut f_sub, &amp;mut io::sink())?;
  
      Ok(())
  }
  
  fn main() {
      let mut data: Vec&lt;u8&gt; = Vec::new();
  
      {
          let size_init = 255_u8;
          encode_recursive(&amp;mut data, size_init);
      }
  
      decode_recursive(&amp;*data, 0).unwrap();
  }
  </code></pre>
  
  <p>See: <a href="https://play.rust-lang.org/?gist=ceff10d39dd4515dcad5a6d1880c7b72&amp;version=stable&amp;backtrace=0" rel="nofollow noreferrer">Rust Playground</a></p>