1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
//! Print some Sim City loading screen status quips
use async_trait::async_trait;
use rand::seq::IndexedRandom;
use rand::{Rng, rng};
use yansi::Paint;
use crate::args::AppConfig;
use crate::data::SIMCITY_LIST;
use crate::io::{csleep, dprint, newline, print};
use crate::modules::Module;
pub struct Simcity;
#[async_trait(?Send)]
impl Module for Simcity {
fn name(&self) -> &'static str {
"mkinitcpio"
}
fn signature(&self) -> String {
"./start-sumcity.sh".to_string()
}
async fn run(&self, appconfig: &AppConfig) {
const SPINNERS: &[&str] = &["/", "-", "\\", "|"];
const SPINNER_SLEEP: u64 = 50;
const TEXT_SLEEP: u64 = 15;
const MAX_SPINNER_LOOPS: u8 = 20;
let mut rng = rng();
let mut simcity = "";
for _ in 0..500 {
let spinner_loops = rng.random_range(1..MAX_SPINNER_LOOPS);
// Message chosen from "data/simcity.txt"
// Thanks https://gist.github.com/erikcox/7e96d031d00d7ecb1a2f
let last_simcity = simcity;
simcity = SIMCITY_LIST.choose(&mut rng).unwrap_or(&"");
// Don't choose the same message twice in a row
while simcity == last_simcity {
// Select another message
simcity = SIMCITY_LIST.choose(&mut rng).unwrap_or(&"");
}
// Choose a status/resolution per "task"
let resolution_id = 1 + rng.random::<u8>() % 100;
let mut resolution = match resolution_id {
1..=4 => "FAIL",
5..=9 => "YES",
10..=14 => "SUCCESS",
_ => "OK",
};
// Prepare and color the messages
let unchecked_checkbox = "[ ] ";
let checked_checkbox = "[o] ";
// Keep track of when the message is first printed
let mut first = true;
'outer: for _ in 0..spinner_loops {
for spinner in SPINNERS {
// Output a message, with a checkbox in front and spinner behind
let msg = format!("{simcity}... {spinner}");
// on first print, text appears letter by letter
if first {
print(unchecked_checkbox).await;
dprint(msg, TEXT_SLEEP).await;
first = false;
} else {
print(unchecked_checkbox).await;
print(msg).await;
}
// Wait a bit, then erase the line
csleep(SPINNER_SLEEP).await;
print("\r").await;
// Don't wait until finished, exit both loops if that is requested
if appconfig.should_exit() {
resolution = "ABORTED";
break 'outer;
}
}
}
// Select the color
let color_func = if resolution == "FAIL" || resolution == "ABORTED" {
// Use red for FAIL
Paint::red
} else if resolution_id > 50 {
// Use white most of the time
Paint::white
} else {
let color_id = 1 + rng.random::<u8>() % 20;
match color_id {
1..=2 => Paint::red,
3..=4 => Paint::green,
5..=6 => Paint::cyan,
7..=10 => Paint::blue,
_ => Paint::white,
}
};
// End of loop, the line has been removed, conclude the status
dprint(checked_checkbox, 10).await;
print(color_func(&format!("{simcity}... {resolution}")).to_string()).await;
if appconfig.should_exit() {
print("\nALL DONE\n").await;
return;
}
newline().await;
}
}
}