Skip to content

Instantly share code, notes, and snippets.

@lovasoa
Last active September 12, 2019 07:49
Show Gist options
  • Save lovasoa/fb1a54bff1c0f39a37d5fd7c38a566db to your computer and use it in GitHub Desktop.
Save lovasoa/fb1a54bff1c0f39a37d5fd7c38a566db to your computer and use it in GitHub Desktop.
rust : convert a writer function to an io::Read
extern crate pipe;
/**
Some libraries (such as handlebars or serde) offer functions that can generate data when given
an object that implements io::Write.
Some other libraries (such as Rocket) can consume data only from objects implementing io::Read.
Here is an example `piper` function that can be used to make these two kinds of libraries together.
Ultimately, the second kind of libraries should be changed to accept writable objects directly.
**/
use pipe::{pipe, PipeReader, PipeWriter};
use std::io::Result;
use std::thread;
/// Starts the given function in a thread and return a reader of the generated data
pub fn piper<F: Send + 'static>(writefn: F) -> PipeReader
where F: FnOnce(PipeWriter) -> Result<()> {
let (reader, writer) = pipe();
thread::spawn(move || writefn(writer));
reader
}
#[cfg(test)]
mod tests {
use std::io::Read;
use std::io::Write;
use super::piper;
#[test]
fn it_works() {
let mut reader = piper(|mut w| w.write_all(b"hello world"));
let mut res = String::new();
reader.read_to_string(&mut res).unwrap();
assert_eq!("hello world", res);
}
#[test]
fn infinite() {
let reader = piper(|mut w| {
loop { w.write_all(b"A")?; }
});
let mut res = String::new();
reader.take(4).read_to_string(&mut res).unwrap();
assert_eq!("AAAA", res);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment