raw_stdio/
lib.rs

1//! This crate provides cross-platform, unbuffered, and direct access to STDIO streams.
2//!
3//! See the documentation of [`RawStdio`] for more details.
4
5use std::{
6    fmt::Arguments,
7    fs::File,
8    io::{stderr, stdin, stdout, IoSlice, IoSliceMut, Read, Write},
9    mem::ManuallyDrop,
10};
11
12#[cfg_attr(unix, path = "unix.rs")]
13#[cfg_attr(windows, path = "windows.rs")]
14mod imp;
15
16/// A raw reference to an STDIO stream.
17///
18/// This type implements [`Read`] and [`Write`] to provide unbuffered and direct access
19/// to an STDIO stream.
20///
21/// # Windows
22///
23/// This type writes and reads raw bytes. If a stream refers to an actual console instead
24/// of being redirect to a file, the encoding depends on the used code page.
25///
26/// # Example
27///
28/// ```
29/// # use std::io::{BufWriter, Write};
30/// # use raw_stdio::raw_stdout;
31/// let mut stdout = BufWriter::new(raw_stdout());
32/// writeln!(stdout, "to stdout").unwrap();
33/// ```
34#[derive(Debug)]
35pub struct RawStdio {
36    file: ManuallyDrop<File>,
37}
38
39/// Returns a [`RawStdio`] handle for STDIN.
40#[inline(always)]
41pub fn raw_stdin() -> RawStdio {
42    imp::build(stdin())
43}
44
45/// Returns a [`RawStdio`] handle for STDOUT.
46#[inline(always)]
47pub fn raw_stdout() -> RawStdio {
48    imp::build(stdout())
49}
50
51/// Returns a [`RawStdio`] handle for STDERR.
52#[inline(always)]
53pub fn raw_stderr() -> RawStdio {
54    imp::build(stderr())
55}
56
57impl Write for RawStdio {
58    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
59        self.file.write(buf)
60    }
61
62    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> std::io::Result<usize> {
63        self.file.write_vectored(bufs)
64    }
65
66    fn flush(&mut self) -> std::io::Result<()> {
67        self.file.flush()
68    }
69
70    fn write_all(&mut self, buf: &[u8]) -> std::io::Result<()> {
71        self.file.write_all(buf)
72    }
73
74    fn write_fmt(&mut self, fmt: Arguments<'_>) -> std::io::Result<()> {
75        self.file.write_fmt(fmt)
76    }
77}
78
79impl Read for RawStdio {
80    fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
81        self.file.read(buf)
82    }
83
84    fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> std::io::Result<usize> {
85        self.file.read_vectored(bufs)
86    }
87
88    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> std::io::Result<usize> {
89        self.file.read_to_end(buf)
90    }
91
92    fn read_to_string(&mut self, buf: &mut String) -> std::io::Result<usize> {
93        self.file.read_to_string(buf)
94    }
95
96    fn read_exact(&mut self, buf: &mut [u8]) -> std::io::Result<()> {
97        self.file.read_exact(buf)
98    }
99}