#file-io #fd #io #sockets #cross-platform #io-stream #file

stdio-override

Rust library for overriding Stdin/Stdout/Stderr with a different stream

5 releases

0.2.0 Jan 26, 2025
0.1.3 May 2, 2019
0.1.2 May 2, 2019
0.1.1 May 2, 2019
0.1.0 May 1, 2019

#116 in Debugging

Download history 1863/week @ 2024-12-04 1369/week @ 2024-12-11 1207/week @ 2024-12-18 655/week @ 2024-12-25 1013/week @ 2025-01-01 1375/week @ 2025-01-08 1439/week @ 2025-01-15 1461/week @ 2025-01-22 1893/week @ 2025-01-29 1649/week @ 2025-02-05 1793/week @ 2025-02-12 1869/week @ 2025-02-19 1699/week @ 2025-02-26 1406/week @ 2025-03-05 1864/week @ 2025-03-12 1621/week @ 2025-03-19

6,975 downloads per month
Used in 6 crates

MIT/Apache

27KB
474 lines

stdio-override

Build Status Latest version Documentation License

A Rust library to easily override Stdio streams in Rust. It works on Unix and Windows platforms.

Usage

Add this to your Cargo.toml:

[dependencies]
stdio-override = "0.1"

and for Rust Edition 2015 add this to your crate root:

extern crate stdio_override;

In Rust Edition 2018 you can simply do:

use stdio_override::*;

Here's an example on how to write stdout into a file:

use std::{fs::{read_to_string, remove_file}, io};
use stdio_override::StdoutOverride;

fn main() -> io::Result<()> {
    let file_name = "./readme_test.txt";

    let guard = StdoutOverride::from_file(file_name)?;
    println!("some output");
    drop(guard);

    let contents = read_to_string(file_name)?;
    assert_eq!("some output\n", contents);
    println!("Outside!");
    remove_file(file_name)?;
    Ok(())
}

On Unix(Linux/MacOS etc.) you can also do the same with sockets:


use std::{
    io::Read,
    net::{TcpListener, TcpStream},
};
use stdio_override::StdoutOverride;

#[cfg(unix)]
fn main() {
    let address = ("127.0.0.1", 5543);

    let listener = TcpListener::bind(address).unwrap();
    let socket = TcpStream::connect(address).unwrap();

    let guard = StdoutOverride::from_io(socket).unwrap();
    println!("12345");
    drop(guard);

    let mut contents = String::new();
    let (mut stream, _) = listener.accept().unwrap();
    stream.read_to_string(&mut contents).unwrap();

    assert_eq!("12345\n", contents);

    println!("Outside!");
}
#[cfg(not(unix))]
fn main() {}

Both will work the same for Stderr and if you want to input Stdin from a file/socket you can do the following:

use std::{fs::File, io::{self, Write}};
use stdio_override::StdinOverride;

fn main() -> io::Result<()> {
    let file_name = "./test_inputs.txt";

    {
        let mut file = File::create(&file_name)?;
        file.write_all(b"Data")?;
    }

    let guard = StdinOverride::from_file(file_name)?;

    let mut inputs = String::new();
    io::stdin().read_line(&mut inputs)?;

    drop(guard);

    assert_eq!("Data", inputs);
    // Stdin is working as usual again, because the guard is dropped.
    Ok(())
}

Dependencies

~220KB