Skip to main content

nostd_print/
lib.rs

1#![no_std]
2
3#[cfg(unix)]
4mod unix;
5#[cfg(windows)]
6mod windows;
7
8pub mod internal {
9    #[cfg(unix)]
10    pub use crate::unix::Writer;
11    #[cfg(windows)]
12    pub use crate::windows::Writer;
13}
14
15#[cfg(unix)]
16pub use crate::unix::read_to_buf;
17#[cfg(windows)]
18pub use crate::windows::read_to_buf;
19
20#[cfg(feature = "alloc")]
21pub mod alloc_feature {
22    extern crate alloc;
23    use alloc::string::String;
24
25    const BUF_SIZE: usize = 128;
26    pub fn read_to_string() -> String {
27        let mut result = String::new();
28        let mut buf = [0u8; BUF_SIZE];
29        while let Some(count) = super::read_to_buf(&mut buf) {
30            if count == 0 {
31                break;
32            } else if count < BUF_SIZE {
33                result.push_str(&String::from_utf8_lossy(&buf[..count]));
34                break;
35            } else {
36                result.push_str(&String::from_utf8_lossy(&buf));
37            }
38        }
39        result
40    }
41}
42#[cfg(feature = "alloc")]
43pub use alloc_feature::*;
44
45#[macro_export]
46macro_rules! print {
47    ($($arg:tt)*) => ({
48        use core::fmt::Write;
49        let mut writer = $crate::internal::Writer::stdout();
50        let _ = write!(&mut writer, "{}", format_args!($($arg)*));
51    })
52}
53#[macro_export]
54macro_rules! println {
55    ($($arg:tt)*) => ({
56        use core::fmt::Write;
57        let mut writer = $crate::internal::Writer::stdout();
58        let _ = writeln!(&mut writer, "{}", format_args!($($arg)*));
59    })
60}
61
62#[macro_export]
63macro_rules! eprint {
64    ($($arg:tt)*) => ({
65        use core::fmt::Write;
66        let mut writer = $crate::internal::Writer::stderr();
67        let _ = write!(&mut writer, "{}", format_args!($($arg)*));
68    })
69}
70#[macro_export]
71macro_rules! eprintln {
72    ($($arg:tt)*) => {{
73        use core::fmt::Write;
74        let mut writer = $crate::internal::Writer::stderr();
75        let _ = writeln!(&mut writer, "{}", format_args!($($arg)*));
76    }};
77}
78
79#[cfg(test)]
80mod test {
81    use crate::*;
82
83    #[allow(dead_code)]
84    #[derive(Debug)]
85    struct Test<'a> {
86        float: f32,
87        int: isize,
88        string: &'static str,
89        nested: Option<&'a Test<'a>>,
90    }
91
92    #[test]
93    fn test_out() {
94        let a = Test {
95            float: 42.1234,
96            int: -42,
97            string: "Hello, world!",
98            nested: Some(&Test {
99                float: -284.213,
100                int: 421,
101                string: "Bye, world!",
102                nested: None,
103            }),
104        };
105
106        print!("Testing stdout: ");
107        println!("{a:#?}");
108        eprint!("Testing stderr: ");
109        eprintln!("{a:#?}");
110    }
111
112    #[test]
113    fn test_in() {
114        let mut buf = [0u8; 100];
115        if read_to_buf(&mut buf).is_some() {
116            let s = unsafe { core::str::from_utf8_unchecked(&buf) };
117            println!("Input: {s:?}");
118        }
119    }
120
121    #[cfg(feature = "alloc")]
122    #[test]
123    fn test_alloc() {
124        let s = read_to_string();
125        println!("String: {s:?}");
126    }
127}