bitcoin_terminal_dashboard/inputs/
events.rs

1use std::env;
2use std::sync::mpsc::{channel, Receiver, RecvError, Sender};
3use std::thread::{self, sleep};
4use std::time::Duration;
5
6use jsonrpc::simple_http::{self, SimpleHttpTransport};
7use jsonrpc::Client;
8
9use super::key::Key;
10use super::InputEvent;
11fn client(url: &str, user: &str, pass: &str) -> Result<Client, simple_http::Error> {
12    let t = SimpleHttpTransport::builder()
13        .url(url)?
14        .auth(user, Some(pass))
15        .build();
16    Ok(Client::with_transport(t))
17}
18
19fn get_client() -> Client {
20    let password = env::var("BITCOIND_PASSWORD").expect("BITCOIND_PASSWORD env variable not set");
21    let username = env::var("BITCOIND_USERNAME").expect("BITCOIND_USERNAME env variable not set");
22    let client = client("127.0.0.1:8332", &username, &password).expect("failed to create client");
23    client
24}
25
26/// A small event handler that wrap crossterm input and tick event. Each event
27/// type is handled in its own thread and returned to a common `Receiver`
28pub struct Events {
29    rx: Receiver<InputEvent>,
30    // Need to be kept around to prevent disposing the sender side.
31    pub tx: Sender<InputEvent>,
32}
33
34impl Events {
35    /// Constructs an new instance of `Events` with the default config.
36    pub fn new(tick_rate: Duration) -> Events {
37        let client = get_client();
38        let (tx, rx) = channel();
39
40        let event_tx = tx.clone();
41        thread::spawn(move || {
42            loop {
43                // poll for tick rate duration, if no event, sent tick event.
44                if crossterm::event::poll(tick_rate).unwrap() {
45                    if let crossterm::event::Event::Key(key) = crossterm::event::read().unwrap() {
46                        let key = Key::from(key);
47                        event_tx.send(InputEvent::Input(key)).unwrap();
48                    }
49                }
50                event_tx.send(InputEvent::Tick).unwrap();
51            }
52        });
53
54        Events { rx, tx }
55    }
56
57    /// Attempts to read an event.
58    /// This function will block the current thread.
59    pub fn next(&self) -> Result<InputEvent, RecvError> {
60        self.rx.recv()
61    }
62}