1
- use std:: fmt;
2
1
use std:: num:: FpCategory ;
3
2
use std:: time:: Duration ;
4
3
use std:: { error:: Error , io} ;
4
+ use std:: { fmt, io:: Stdout } ;
5
5
6
6
use chrono:: Local ;
7
7
use metrics:: Unit ;
8
- use termion:: { event:: Key , input:: MouseTerminal , raw:: IntoRawMode , screen:: IntoAlternateScreen } ;
9
- use tui:: {
10
- backend:: TermionBackend ,
8
+ use ratatui:: {
9
+ backend:: CrosstermBackend ,
10
+ crossterm:: {
11
+ event:: KeyCode ,
12
+ execute,
13
+ terminal:: { disable_raw_mode, enable_raw_mode, EnterAlternateScreen , LeaveAlternateScreen } ,
14
+ } ,
11
15
layout:: { Constraint , Direction , Layout } ,
12
16
style:: { Color , Modifier , Style } ,
13
- text:: { Span , Spans } ,
17
+ text:: { Line , Span } ,
14
18
widgets:: { Block , Borders , List , ListItem , Paragraph , Wrap } ,
15
19
Terminal ,
16
20
} ;
@@ -27,23 +31,23 @@ mod selector;
27
31
use self :: selector:: Selector ;
28
32
29
33
fn main ( ) -> Result < ( ) , Box < dyn Error > > {
30
- let stdout = io:: stdout ( ) . into_raw_mode ( ) ?;
31
- let stdout = MouseTerminal :: from ( stdout) . into_alternate_screen ( ) ?;
32
- let backend = TermionBackend :: new ( stdout) ;
33
- let mut terminal = Terminal :: new ( backend) ?;
34
+ let terminal = init_terminal ( ) ?;
35
+ let result = run ( terminal) ;
36
+ restore_terminal ( ) ?;
37
+ result
38
+ }
34
39
35
- let mut events = InputEvents :: new ( ) ;
40
+ fn run ( mut terminal : Terminal < CrosstermBackend < Stdout > > ) -> Result < ( ) , Box < dyn Error > > {
36
41
let address = std:: env:: args ( ) . nth ( 1 ) . unwrap_or_else ( || "127.0.0.1:5000" . to_owned ( ) ) ;
37
42
let client = metrics_inner:: Client :: new ( address) ;
38
43
let mut selector = Selector :: new ( ) ;
39
-
40
44
loop {
41
45
terminal. draw ( |f| {
42
46
let chunks = Layout :: default ( )
43
47
. direction ( Direction :: Vertical )
44
48
. margin ( 1 )
45
49
. constraints ( [ Constraint :: Length ( 4 ) , Constraint :: Percentage ( 90 ) ] . as_ref ( ) )
46
- . split ( f. size ( ) ) ;
50
+ . split ( f. area ( ) ) ;
47
51
48
52
let current_dt = Local :: now ( ) . format ( " (%Y/%m/%d %I:%M:%S %p)" ) . to_string ( ) ;
49
53
let client_state = match client. state ( ) {
@@ -58,9 +62,9 @@ fn main() -> Result<(), Box<dyn Error>> {
58
62
spans. push ( Span :: raw ( s) ) ;
59
63
}
60
64
61
- Spans :: from ( spans)
65
+ Line :: from ( spans)
62
66
}
63
- ClientState :: Connected => Spans :: from ( vec ! [
67
+ ClientState :: Connected => Line :: from ( vec ! [
64
68
Span :: raw( "state: " ) ,
65
69
Span :: styled( "connected" , Style :: default ( ) . fg( Color :: Green ) ) ,
66
70
] ) ,
@@ -75,7 +79,7 @@ fn main() -> Result<(), Box<dyn Error>> {
75
79
76
80
let text = vec ! [
77
81
client_state,
78
- Spans :: from( vec![
82
+ Line :: from( vec![
79
83
Span :: styled( "controls: " , Style :: default ( ) . add_modifier( Modifier :: BOLD ) ) ,
80
84
Span :: raw( "up/down = scroll, q = quit" ) ,
81
85
] ) ,
@@ -149,21 +153,31 @@ fn main() -> Result<(), Box<dyn Error>> {
149
153
150
154
// Poll the event queue for input events. `next` will only block for 1 second,
151
155
// so our screen is never stale by more than 1 second.
152
- if let Some ( input) = events . next ( ) ? {
153
- match input {
154
- Key :: Char ( 'q' ) => break ,
155
- Key :: Up => selector. previous ( ) ,
156
- Key :: Down => selector. next ( ) ,
157
- Key :: PageUp => selector. top ( ) ,
158
- Key :: PageDown => selector. bottom ( ) ,
156
+ if let Some ( input) = InputEvents :: next ( ) ? {
157
+ match input. code {
158
+ KeyCode :: Char ( 'q' ) => break ,
159
+ KeyCode :: Up => selector. previous ( ) ,
160
+ KeyCode :: Down => selector. next ( ) ,
161
+ KeyCode :: PageUp => selector. top ( ) ,
162
+ KeyCode :: PageDown => selector. bottom ( ) ,
159
163
_ => { }
160
164
}
161
165
}
162
166
}
163
-
164
167
Ok ( ( ) )
165
168
}
166
169
170
+ fn init_terminal ( ) -> io:: Result < Terminal < CrosstermBackend < Stdout > > > {
171
+ enable_raw_mode ( ) ?;
172
+ execute ! ( io:: stdout( ) , EnterAlternateScreen ) ?;
173
+ Terminal :: new ( CrosstermBackend :: new ( io:: stdout ( ) ) )
174
+ }
175
+
176
+ fn restore_terminal ( ) -> io:: Result < ( ) > {
177
+ disable_raw_mode ( ) ?;
178
+ execute ! ( io:: stdout( ) , LeaveAlternateScreen )
179
+ }
180
+
167
181
fn u64_to_displayable ( value : u64 , unit : Option < Unit > ) -> String {
168
182
let unit = match unit {
169
183
None => return value. to_string ( ) ,
0 commit comments