title: Perpetual tokio TCP stream (client)
body: <p><strong>Foreword, you can skip to the next section</strong></p>
  
  <p>So I decided to try Rust for my new relatively small project, because I like that it produces a single executable which is easy to deploy on my ARM-based target with relatively little resources in terms of RAM and disk space. I have no previous experience with Rust, but a lot of experience with other languages, and so far I am getting somewhat disappointed. It seems that for many Rust libraries and probably Rust itself, the APIs are changing so fast that 90% of sample code found online will not compile with latest versions of libraries like <code>tokio</code>, <code>tokio-util</code> etc. Also, the documentation is often misleading. For example, if you Google for <code>LinesCodec</code> it will show up in <code>tokio_io::codec::LinesCodec</code>, <code>tokio::codec::LinesCodec</code>, <code>tokio_codec::LinesCodec</code> and <code>tokio_util::codec::LinesCodec</code>, which ultimately seems to be one to use as of today. Same confusion goes for other things like <code>FramedRead</code>, which had an <code>and_then</code> and <code>map</code> member functions in some versions, but they doesn't seem to exist in the latest version. Lastly, the amount of questions and answers related to Rust on SO is far less than for other languages I've used, which makes it harder to start using Rust. What I'm trying to do for the past 2 days is solved relatively easily in most programming languages, and I believe, there must be an easy solution in Rust as well, but so far I had no success.</p>
  
  <p><strong>Question itself</strong></p>
  
  <p><em>I need to connect a TCP client to a remote server and indefinitely read and process data line by line as it comes in</em>. This needs to be done asynchronously because the same process also acts as a HTTP server, so I'm using <code>tokio</code>.</p>
  
  <p>As far as I understand, the somewhat common way is to use <code>TcpStream</code>, slit it to RX/TX parts, then I'm trying to hook up a <code>LinesCodec</code> (with <code>FramedRead</code>) but I'm unable to hook all these together without getting compilation errors.</p>
  
  <pre><code>[dependencies]
  futures = "*"
  hyper = "*"
  tokio = { version = "*", features = ["full"] }
  tokio-util = "0.2.0"
  tokio-modbus = { version = "*", features = ["tcp", "server", "tcp-server-unstable"], git = "https://github.com/slowtec/tokio-modbus" }
  </code></pre>
  
  <pre class="lang-rust prettyprint-override"><code>let stream = TcpStream::connect("172.16.100.10:1001").await.unwrap();
  let transport = FramedRead::new(stream, LinesCodec::new()); // need to split?
  /* ... what to do next to process incoming data line-by-line ...? */
  </code></pre>
  
  <p>So far I came with this solution, not sure how good it is though</p>
  
  <pre class="lang-rust prettyprint-override"><code>tokio::spawn(async {
      let connection = TcpStream::connect("172.16.100.10:1001").await.unwrap();
      let mut reader = BufReader::new(connection);
  
      loop {
          let mut line = String::new();
          reader.read_line(&amp;mut line).await.unwrap();
          println!("{}", line);
      }
  });
  </code></pre>