1 use crate::util::{RandomSignal, SinSignal, StatefulList, TabsState};
2 
3 const TASKS: [&str; 24] = [
4     "Item1", "Item2", "Item3", "Item4", "Item5", "Item6", "Item7", "Item8", "Item9", "Item10",
5     "Item11", "Item12", "Item13", "Item14", "Item15", "Item16", "Item17", "Item18", "Item19",
6     "Item20", "Item21", "Item22", "Item23", "Item24",
7 ];
8 
9 const LOGS: [(&str, &str); 26] = [
10     ("Event1", "INFO"),
11     ("Event2", "INFO"),
12     ("Event3", "CRITICAL"),
13     ("Event4", "ERROR"),
14     ("Event5", "INFO"),
15     ("Event6", "INFO"),
16     ("Event7", "WARNING"),
17     ("Event8", "INFO"),
18     ("Event9", "INFO"),
19     ("Event10", "INFO"),
20     ("Event11", "CRITICAL"),
21     ("Event12", "INFO"),
22     ("Event13", "INFO"),
23     ("Event14", "INFO"),
24     ("Event15", "INFO"),
25     ("Event16", "INFO"),
26     ("Event17", "ERROR"),
27     ("Event18", "ERROR"),
28     ("Event19", "INFO"),
29     ("Event20", "INFO"),
30     ("Event21", "WARNING"),
31     ("Event22", "INFO"),
32     ("Event23", "INFO"),
33     ("Event24", "WARNING"),
34     ("Event25", "INFO"),
35     ("Event26", "INFO"),
36 ];
37 
38 const EVENTS: [(&str, u64); 24] = [
39     ("B1", 9),
40     ("B2", 12),
41     ("B3", 5),
42     ("B4", 8),
43     ("B5", 2),
44     ("B6", 4),
45     ("B7", 5),
46     ("B8", 9),
47     ("B9", 14),
48     ("B10", 15),
49     ("B11", 1),
50     ("B12", 0),
51     ("B13", 4),
52     ("B14", 6),
53     ("B15", 4),
54     ("B16", 6),
55     ("B17", 4),
56     ("B18", 7),
57     ("B19", 13),
58     ("B20", 8),
59     ("B21", 11),
60     ("B22", 9),
61     ("B23", 3),
62     ("B24", 5),
63 ];
64 
65 pub struct Signal<S: Iterator> {
66     source: S,
67     pub points: Vec<S::Item>,
68     tick_rate: usize,
69 }
70 
71 impl<S> Signal<S>
72 where
73     S: Iterator,
74 {
on_tick(&mut self)75     fn on_tick(&mut self) {
76         for _ in 0..self.tick_rate {
77             self.points.remove(0);
78         }
79         self.points
80             .extend(self.source.by_ref().take(self.tick_rate));
81     }
82 }
83 
84 pub struct Signals {
85     pub sin1: Signal<SinSignal>,
86     pub sin2: Signal<SinSignal>,
87     pub window: [f64; 2],
88 }
89 
90 impl Signals {
on_tick(&mut self)91     fn on_tick(&mut self) {
92         self.sin1.on_tick();
93         self.sin2.on_tick();
94         self.window[0] += 1.0;
95         self.window[1] += 1.0;
96     }
97 }
98 
99 pub struct Server<'a> {
100     pub name: &'a str,
101     pub location: &'a str,
102     pub coords: (f64, f64),
103     pub status: &'a str,
104 }
105 
106 pub struct App<'a> {
107     pub title: &'a str,
108     pub should_quit: bool,
109     pub tabs: TabsState<'a>,
110     pub show_chart: bool,
111     pub progress: f64,
112     pub sparkline: Signal<RandomSignal>,
113     pub tasks: StatefulList<&'a str>,
114     pub logs: StatefulList<(&'a str, &'a str)>,
115     pub signals: Signals,
116     pub barchart: Vec<(&'a str, u64)>,
117     pub servers: Vec<Server<'a>>,
118     pub enhanced_graphics: bool,
119 }
120 
121 impl<'a> App<'a> {
new(title: &'a str, enhanced_graphics: bool) -> App<'a>122     pub fn new(title: &'a str, enhanced_graphics: bool) -> App<'a> {
123         let mut rand_signal = RandomSignal::new(0, 100);
124         let sparkline_points = rand_signal.by_ref().take(300).collect();
125         let mut sin_signal = SinSignal::new(0.2, 3.0, 18.0);
126         let sin1_points = sin_signal.by_ref().take(100).collect();
127         let mut sin_signal2 = SinSignal::new(0.1, 2.0, 10.0);
128         let sin2_points = sin_signal2.by_ref().take(200).collect();
129         App {
130             title,
131             should_quit: false,
132             tabs: TabsState::new(vec!["Tab0", "Tab1", "Tab2"]),
133             show_chart: true,
134             progress: 0.0,
135             sparkline: Signal {
136                 source: rand_signal,
137                 points: sparkline_points,
138                 tick_rate: 1,
139             },
140             tasks: StatefulList::with_items(TASKS.to_vec()),
141             logs: StatefulList::with_items(LOGS.to_vec()),
142             signals: Signals {
143                 sin1: Signal {
144                     source: sin_signal,
145                     points: sin1_points,
146                     tick_rate: 5,
147                 },
148                 sin2: Signal {
149                     source: sin_signal2,
150                     points: sin2_points,
151                     tick_rate: 10,
152                 },
153                 window: [0.0, 20.0],
154             },
155             barchart: EVENTS.to_vec(),
156             servers: vec![
157                 Server {
158                     name: "NorthAmerica-1",
159                     location: "New York City",
160                     coords: (40.71, -74.00),
161                     status: "Up",
162                 },
163                 Server {
164                     name: "Europe-1",
165                     location: "Paris",
166                     coords: (48.85, 2.35),
167                     status: "Failure",
168                 },
169                 Server {
170                     name: "SouthAmerica-1",
171                     location: "São Paulo",
172                     coords: (-23.54, -46.62),
173                     status: "Up",
174                 },
175                 Server {
176                     name: "Asia-1",
177                     location: "Singapore",
178                     coords: (1.35, 103.86),
179                     status: "Up",
180                 },
181             ],
182             enhanced_graphics,
183         }
184     }
185 
on_up(&mut self)186     pub fn on_up(&mut self) {
187         self.tasks.previous();
188     }
189 
on_down(&mut self)190     pub fn on_down(&mut self) {
191         self.tasks.next();
192     }
193 
on_right(&mut self)194     pub fn on_right(&mut self) {
195         self.tabs.next();
196     }
197 
on_left(&mut self)198     pub fn on_left(&mut self) {
199         self.tabs.previous();
200     }
201 
on_key(&mut self, c: char)202     pub fn on_key(&mut self, c: char) {
203         match c {
204             'q' => {
205                 self.should_quit = true;
206             }
207             't' => {
208                 self.show_chart = !self.show_chart;
209             }
210             _ => {}
211         }
212     }
213 
on_tick(&mut self)214     pub fn on_tick(&mut self) {
215         // Update progress
216         self.progress += 0.001;
217         if self.progress > 1.0 {
218             self.progress = 0.0;
219         }
220 
221         self.sparkline.on_tick();
222         self.signals.on_tick();
223 
224         let log = self.logs.items.pop().unwrap();
225         self.logs.items.insert(0, log);
226 
227         let event = self.barchart.pop().unwrap();
228         self.barchart.insert(0, event);
229     }
230 }
231