ioctl_term_light/
stdio.rs

1use crate::impl_std_fd;
2
3#[cfg(any(feature = "stdio", feature = "stdin"))]
4impl_std_fd!(stdin, 0);
5#[cfg(any(feature = "stdio", feature = "stdout"))]
6impl_std_fd!(stdout, 1);
7#[cfg(any(feature = "stdio", feature = "stderr"))]
8impl_std_fd!(stderr, 2);
9
10#[cfg(any(
11    feature = "stdio",
12    feature = "stdin",
13    feature = "stdout",
14    feature = "stderr"
15))]
16#[macro_export]
17macro_rules! impl_std_fd {
18    ($name:ident, $fd:literal) => {
19        pub mod $name {
20            use $crate::c::{c_int, ioctl_get_dimensions};
21            use $crate::Dimensions;
22            pub const FILENO: c_int = $fd;
23
24            /// Attempts to obtain a tuple with (rows, columns) of the current process'es stdout, stdin or stderr.
25            ///
26            /// Examples
27            ///
28            /// ```
29            /// use ioctl_term_light::stdout;
30            /// assert_eq!(stdout::get_dimensions(), None);
31            /// ```
32            ///
33            /// ```
34            /// use ioctl_term_light::stdin;
35            /// assert_eq!(stdin::get_dimensions(), None);
36            /// ```
37            ///
38            /// ```
39            /// use ioctl_term_light::stderr;
40            /// assert_eq!(stderr::get_dimensions(), None);
41            /// ```
42            pub fn get_dimensions() -> Option<(u16, u16)> {
43                let ws = unsafe { ioctl_get_dimensions(FILENO) };
44                if ws.ws_col == 0 || ws.ws_row == 0 {
45                    None
46                } else {
47                    Some((ws.ws_col as u16, ws.ws_row as u16))
48                }
49            }
50            /// Returns [Dimensions] process'es stdout, stdin or stderr.
51            ///
52            /// Examples
53            ///
54            /// ```
55            /// use ioctl_term_light::Dimensions;
56            /// use ioctl_term_light::stdout;
57            ///
58            /// assert_eq!(stdout::dimensions(), Dimensions::from((0u16, 0u16)));
59            /// ```
60            ///
61            /// ```
62            /// use ioctl_term_light::Dimensions;
63            /// use ioctl_term_light::stdout;
64            ///
65            /// assert_eq!(stdout::dimensions(), Dimensions::from((0u16, 0u16)));
66            /// ```
67            ///
68            /// ```
69            /// use ioctl_term_light::Dimensions;
70            /// use ioctl_term_light::stdout;
71            ///
72            /// assert_eq!(stdout::dimensions(), Dimensions::from((0u16, 0u16)));
73            /// ```
74            pub fn dimensions() -> Dimensions {
75                Dimensions::from(get_dimensions())
76            }
77
78            #[cfg(test)]
79            mod tests {
80                use super::{dimensions, get_dimensions};
81                use $crate::Dimensions;
82
83                #[test]
84                fn test_get_dimensions() {
85                    let dimensions = get_dimensions();
86                    assert_ne!(
87                        dimensions, None,
88                        "expected get_dimensions() to not return None"
89                    );
90                    assert_ne!(
91                        dimensions,
92                        Some((0, 0)),
93                        "expected get_dimensions() to not return Some((0, 0))"
94                    );
95                }
96
97                #[test]
98                fn test_dimensions() {
99                    let dimensions = dimensions();
100                    let unexpected = Dimensions::from((0u16, 0u16));
101                    assert_ne!(
102                        dimensions, unexpected,
103                        "expected get_dimensions() to not return {unexpected:#?}"
104                    );
105                }
106            }
107        }
108    };
109}