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 pub quit: bool,
13}
14
15impl ChaiApp for MyApp {
16 fn new() -> Self {
17 Self {
18 counter: 0,
19 quit: false,
20 }
21 }
22 fn update(&mut self) {
23 self.counter += 1;
24 }
25 fn draw(&mut self, f: &mut Frame) {
26 let area = f.area();
27 f.render_widget(Clear, area);
28 let style = match self.counter % 3 {
29 0 => Style::default().fg(Color::Red),
30 1 => Style::default().fg(Color::Green),
31 _ => Style::default().fg(Color::Blue),
32 };
33 let paragraph = Paragraph::new(format!("Counter: {}", self.counter))
34 .alignment(ratatui::layout::Alignment::Center)
35 .style(style);
36 let block = Block::default()
37 .title("'c' to reset | 'q' to quit | ctrl+c to quit")
38 .borders(Borders::ALL);
39 f.render_widget(paragraph.block(block), area);
40 }
41 fn handle_input(&mut self, data: &[u8]) {
42 match data {
43 b"c" => self.counter = 0,
44 b"q" | b"Q" => self.quit = true,
45 _ => {}
47 }
48 }
49 fn should_quit(&self) -> bool {
50 self.quit
51 }
52}
53
54#[tokio::main]
55async fn main() {
56 let host_key =
57 load_host_keys("./examples/host_keys/id_ed25519").expect("Failed to load host keys");
58 let mut methods = MethodSet::empty();
59 methods.push(MethodKind::None);
60
61 let config = Config {
62 inactivity_timeout: Some(std::time::Duration::from_secs(3600)),
63 auth_rejection_time: std::time::Duration::from_secs(3),
64 auth_rejection_time_initial: Some(std::time::Duration::from_secs(0)),
65 keys: vec![host_key],
66 methods,
67 ..Default::default()
68 };
69
70 let mut server = ChaiServer::<MyApp>::new(2222).with_tick_rate(std::time::Duration::from_millis(250));
71 server.run(config).await.expect("Failed running server");
72}