1use chai_framework::{ChaiApp, ChaiServer, load_host_keys};
2use ratatui::{
3 Frame,
4 style::{Color, Style},
5 widgets::{Block, Borders, Clear, Paragraph},
6};
7use russh::{MethodKind, MethodSet, server::Config};
8
9#[derive(Copy, Clone)]
10pub struct MyApp {
11 pub counter: usize,
12}
13
14impl ChaiApp for MyApp {
15 fn new() -> Self {
16 Self { counter: 0 }
17 }
18 fn update(&mut self) {
19 self.counter += 1;
20 }
21 fn draw(&mut self, f: &mut Frame) {
22 let area = f.area();
23 f.render_widget(Clear, area);
24 let style = match self.counter % 3 {
25 0 => Style::default().fg(Color::Red),
26 1 => Style::default().fg(Color::Green),
27 _ => Style::default().fg(Color::Blue),
28 };
29 let paragraph = Paragraph::new(format!("Counter: {}", self.counter))
30 .alignment(ratatui::layout::Alignment::Center)
31 .style(style);
32 let block = Block::default()
33 .title("Press 'c' to reset the counter!")
34 .borders(Borders::ALL);
35 f.render_widget(paragraph.block(block), area);
36 }
37 fn handle_input(&mut self, data: &[u8]) {
38 if data == b"c" {
39 self.counter = 0;
40 }
41 }
42}
43
44#[tokio::main]
45async fn main() {
46 let host_key =
47 load_host_keys("./examples/authorized_keys/ed_25519").expect("Failed to load host keys");
48 let mut methods = MethodSet::empty();
49 methods.push(MethodKind::None);
50
51 let config = Config {
52 inactivity_timeout: Some(std::time::Duration::from_secs(3600)),
53 auth_rejection_time: std::time::Duration::from_secs(3),
54 auth_rejection_time_initial: Some(std::time::Duration::from_secs(0)),
55 keys: vec![host_key],
56 methods,
57 ..Default::default()
58 };
59
60 let mut server = ChaiServer::<MyApp>::new(2222);
61 server.run(config).await.expect("Failed running server");
62}