runnel

Crates.iorunnel
lib.rsrunnel
version0.4.0
created_at2021-01-24 12:25:55.583294+00
updated_at2025-08-19 14:19:15.370156+00
descriptionthe pluggable io stream. now support: stdio, string io, in memory pipe, line pipe
homepage
repositoryhttps://github.com/aki-akaguma/runnel
max_upload_size
id346001
size118,204
(aki-akaguma)

documentation

README

runnel

crate Docs Rust Version Apache2/MIT licensed Test ubu Test mac Test win

The pluggable io stream. now support: stdio, string io, in memory pipe, in memory line pipe.

Features

  • support common operation: stdin, stdout, stderr, stringin, stringout, pipein, pipeout, linepipein and linepipeout.
  • thin interface
  • support testing io stream
  • minimum support rustc 1.60.0 (7737e0b5c 2022-04-04)

Examples

Example of stdio :

use runnel::RunnelIoeBuilder;
let sioe = RunnelIoeBuilder::new().build();

Example of stringio :

use runnel::RunnelIoeBuilder;
use std::io::{BufRead, Write};

let sioe = RunnelIoeBuilder::new()
    .fill_stringio_with_str("ABCDE\nefgh\n")
    .build();

// pluggable input stream
let mut lines_iter = sioe.pg_in().lines().map(|l| l.unwrap());
assert_eq!(lines_iter.next(), Some(String::from("ABCDE")));
assert_eq!(lines_iter.next(), Some(String::from("efgh")));
assert_eq!(lines_iter.next(), None);

// pluggable output stream
#[rustfmt::skip]
let res = sioe.pg_out().lock()
    .write_fmt(format_args!("{}\nACBDE\nefgh\n", 1234));
assert!(res.is_ok());
assert_eq!(sioe.pg_out().lock().buffer_to_string(), "1234\nACBDE\nefgh\n");

// pluggable error stream
#[rustfmt::skip]
let res = sioe.pg_err().lock()
    .write_fmt(format_args!("{}\nACBDE\nefgh\n", 1234));
assert!(res.is_ok());
assert_eq!(sioe.pg_err().lock().buffer_to_string(), "1234\nACBDE\nefgh\n");

Example of pipeio :

use runnel::RunnelIoeBuilder;
use runnel::medium::pipeio::pipe;
use std::io::{BufRead, Write};

// create in memory pipe
let (a_out, a_in) = pipe(1);

// a working thread
let sioe = RunnelIoeBuilder::new()
    .fill_stringio_with_str("ABCDE\nefgh\n")
    .pg_out(a_out)    // pluggable pipe out
    .build();
let handler = std::thread::spawn(move || {
    for line in sioe.pg_in().lines().map(|l| l.unwrap()) {
        let mut out = sioe.pg_out().lock();
        let _ = out.write_fmt(format_args!("{}\n", line));
        let _ = out.flush();
    }
});

// a main thread
let sioe = RunnelIoeBuilder::new()
    .fill_stringio_with_str("ABCDE\nefgh\n")
    .pg_in(a_in)      // pluggable pipe in
    .build();
let mut lines_iter = sioe.pg_in().lines().map(|l| l.unwrap());
assert_eq!(lines_iter.next(), Some(String::from("ABCDE")));
assert_eq!(lines_iter.next(), Some(String::from("efgh")));
assert_eq!(lines_iter.next(), None);

assert!(handler.join().is_ok());

Example of linepipeio :

use runnel::RunnelIoeBuilder;
use runnel::medium::linepipeio::line_pipe;
use std::io::{BufRead, Write};

// create in memory line pipe
let (a_out, a_in) = line_pipe(1);

// a working thread
let sioe = RunnelIoeBuilder::new()
    .fill_stringio_with_str("ABCDE\nefgh\n")
    .pg_out(a_out)    // pluggable pipe out
    .build();
let handler = std::thread::spawn(move || {
    for line in sioe.pg_in().lines().map(|l| l.unwrap()) {
        let _ = sioe.pg_out().write_line(line);
        let _ = sioe.pg_out().flush_line();
    }
});

// a main thread
let sioe = RunnelIoeBuilder::new()
    .fill_stringio_with_str("ABCDE\nefgh\n")
    .pg_in(a_in)      // pluggable pipe in
    .build();
let mut lines_iter = sioe.pg_in().lines().map(|l| l.unwrap());
assert_eq!(lines_iter.next(), Some(String::from("ABCDE")));
assert_eq!(lines_iter.next(), Some(String::from("efgh")));
assert_eq!(lines_iter.next(), None);

assert!(handler.join().is_ok());

Changelogs

This crate's changelog here.

License

This project is licensed under either of

at your option.

Commit count: 55

cargo fmt