counter/
counter.rs

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}