term_lab/
info.rs

1use cfg_if::cfg_if;
2use std::fmt;
3use std::io::{ Stdout, Stderr, Stdin };
4
5#[derive(Debug, Clone, Copy)]
6pub struct Size {
7  pub width: u16,
8  pub height: u16,
9}
10
11impl fmt::Display for Size {
12  fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13    write!(f, "{}x{}", self.width, self.height)
14  }
15}
16
17impl Size {
18  #[inline(always)]
19  pub fn new(width: u16, height: u16) -> Self {
20    Self { width, height }
21  }
22}
23
24/// Trait to get the size of the terminal
25pub trait TermInfo {
26  /// Returns the size of this stream in the terminal
27  fn size(&mut self) -> Option<Size>;
28}
29
30macro_rules! impl_all {
31  // Prevent bug when using self
32  (
33    $self:ident;
34    $out_size:expr, $err_size:expr, $in_size:expr
35  ) =>
36  {
37    impl TermInfo for Stdout {
38      #[inline(always)]
39      fn size(&mut $self) -> Option<Size> { $out_size }
40    }
41    impl TermInfo for Stderr {
42      #[inline(always)]
43      fn size(&mut $self) -> Option<Size> { $err_size }
44    }
45    impl TermInfo for Stdin {
46      #[inline(always)]
47      fn size(&mut $self) -> Option<Size> { $in_size }
48    }
49  };
50}
51
52cfg_if!(
53  if #[cfg(windows)] {
54    mod windows;
55    use windows::{ size_of, stdin_size };
56    impl_all!(self; size_of(self), size_of(self), stdin_size());
57  } else if #[cfg(unix)] {
58    mod unix;
59    use unix::size_of;
60    impl_all!(self; size_of(self), size_of(self), size_of(self));
61  } else {
62    impl_all!(self; None, None, None);
63  }
64);