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