Resume output of resolution field
[pulga.git] / src / main.rs
blobdc907c11c13ccb9f24eecfc2e5dd3f5ff0a322f7
1 #[allow(dead_code)]
2 mod _arts;
3 #[rustfmt::skip]
4 mod distros;
5 mod pulga;
6 mod screenres;
7 #[cfg(feature = "use_xlib")]
8 mod screenresx11;
9 mod sysinfo;
10 mod uname;
11 mod util;
13 use crate::{pulga::UserData, util::get_rand};
14 use std::io::{self, BufWriter, Write};
16 use smallvec::SmallVec;
17 use sugars::boxed;
18 use termion::{color::*, cursor::*};
20 use std::{collections::HashMap, env, mem};
22 fn display_information_and_logo(text: String, art: &str, horizontal_offset: u16) -> io::Result<()> {
23     let lines: SmallVec<[&str; 128]> = text.lines().map(|x| x.trim()).collect();
25     // Logo colors table
26     #[rustfmt::skip]
27     let color_map = {
28         let mut m = HashMap::<char, Box<dyn Color>>::new();
29         m.insert('k', boxed!(Black  )); // k => Black
30         m.insert('r', boxed!(Red    )); // r => Red
31         m.insert('g', boxed!(Green  )); // g => Green
32         m.insert('y', boxed!(Yellow )); // y => Yellow
33         m.insert('b', boxed!(Blue   )); // b => Blue
34         m.insert('m', boxed!(Magenta)); // m => Magenta
35         m.insert('c', boxed!(Cyan   )); // c => Cyan
36         m.insert('w', boxed!(White  )); // w => White
37         m.insert('R', boxed!(Reset  )); // R => Reset all
38         m
39     };
41     let logo = art.chars().collect::<SmallVec<[char; 8192]>>();
42     let mut output = BufWriter::new(io::stdout());
44     let mut i = 0;
46     while i < logo.len() - 2 {
47         match &logo[i..=i + 2] {
48             ['{', color_id, '}'] => {
49                 let color: &dyn Color = match color_map.get(&color_id) {
50                     Some(color) => color.as_ref(),
51                     None => panic!("Unexpected color_id '{}'", color_id),
52                 };
54                 i += 2;
55                 write!(output, "{}", Fg(color))?;
56             },
57             ['\n', ..] => {
58                 write!(output, "\n   ")?;
59             },
60             other => {
61                 write!(
62                     output,
63                     "{}",
64                     other.get(0).expect("Slice shouldn't be empty")
65                 )?;
66             },
67         }
68         i += 1;
69     }
71     // Show the remaining stuff
72     for remaining in logo.iter().skip(i) {
73         write!(output, "{}", remaining)?;
74     }
75     write!(output, "\n")?;
77     let logo_lines = logo.iter().filter(|x| **x == '\n').count() as u16;
78     let info_lines = lines.len() as u16;
79     let up_how_many_times = info_lines + (logo_lines - info_lines) / 2 + 1;
81     // Code to insert information at the side of the logo
82     write!(output, "{}", Up(up_how_many_times))?;
84     for line in lines.iter() {
85         write!(
86             output,
87             "{} {}{}{}",
88             Right(horizontal_offset),
89             line,
90             Left(u16::MAX), // Go to the beginning, for sure
91             Down(1)
92         )?;
93     }
94     write!(output, "{}", Down(up_how_many_times - lines.len() as u16))?;
95     Ok(())
98 fn main() -> io::Result<()> {
99     // dbg!(scwayland::get_screen_resolution());
101     let UserData {
102         username,
103         hostname,
104         cpu_info,
105         uptime,
106         hmd,
107         shell,
108         editor,
109         distro,
110         kernel_version,
111         desk_env,
112         monitor_res,
113         used_memory,
114         total_memory,
115         cwd: _, // Unused
116     } = pulga::get_user_data();
118     #[rustfmt::skip]
119     let text = format!(
120         "{c}{}{R}@{c}{}{R}\n\
121         \n\
122          {c}{}{w}: {r}{}{R}\n\
123          {c}{}{w}: {r}{}{R}\n\
124          {c}{}{w}: {r}{}/{R}\n\
125          {c}{}{w}: {r}{}{R}\n\
126          {c}{}{w}: {r}{}{R}\n\
127          {c}{}{w}: {r}{}{R}\n\
128          {c}{}{w}: {r}{}{R}\n\
129          {c}{}{w}: {r}{}{R}\n\
130          {c}{}{w}: {r}{}{R}\n\
131          {c}{}{w}: {r}{}{R} / {r}{}{R}",
132         username, hostname,
133         "cpu", cpu_info,
134         "uptime", uptime,
135         "home", hmd,
136         "shell", shell,
137         "editor", editor,
138         "distro", distro,
139         "kernel", kernel_version,
140         "desktop env.", desk_env,
141         "monitor", monitor_res,
142         "memory usage", used_memory, total_memory,
143         c = Fg(LightCyan),
144         w = Fg(LightBlack),
145         R = Fg(Reset),
146         r = Fg(LightRed),
147     );
149     let mut is_random = false;
151     // Small arg parsing out of nowhere
152     for arg in env::args().skip(1) {
153         if arg == "--random" || arg == "-r" {
154             is_random = true;
155         }
156     }
158     let distro = if is_random {
159         // This is seriously hacky
160         unsafe { mem::transmute(get_rand(distros::DISTROS) as i8) }
161     } else {
162         distros::Distro::Debian
163     };
165     let (offset, art) = distros::choose_art(distro);
166     display_information_and_logo(text, art, offset)