qsk/
recorder.rs

1use std::fs::File;
2use std::io::LineWriter;
3use std::path::PathBuf;
4
5use async_std::channel::unbounded;
6use async_std::channel::Receiver;
7use async_std::channel::Sender;
8use async_std::prelude::StreamExt;
9use async_std::task::block_on;
10
11use log::error;
12use serde::{
13    ser::{SerializeSeq, Serializer},
14    Deserialize, Serialize,
15};
16use serde_json;
17
18use qsk_types::control_code::ControlCode;
19use qsk_types::layer_composer::InputTransformer;
20use crate::errors::Result;
21use crate::events::InputEvent;
22
23#[derive(Serialize, Deserialize, Debug)]
24pub enum Log {
25    In(InputEvent),
26    Out(ControlCode),
27}
28
29pub struct Recorder {
30    receiver: Receiver<Log>,
31}
32
33impl Recorder {
34    pub fn wrap(it: Box<dyn InputTransformer + Send>) -> (Self, Listener) {
35        let (sender, receiver) = unbounded();
36        (Recorder { receiver }, Listener { inner: it, sender })
37    }
38
39    pub async fn record(
40        &mut self,
41        p: PathBuf,
42    ) -> std::result::Result<(), Box<dyn std::error::Error>> {
43        let file = File::create(p)?;
44        let file = LineWriter::with_capacity(1, file);
45
46        let mut ser = serde_json::Serializer::pretty(file);
47        let mut seq = ser.serialize_seq(None)?;
48        while let Some(ie) = self.receiver.next().await {
49            seq.serialize_element(&ie)?;
50        }
51        seq.end()?;
52        Ok(())
53    }
54}
55
56pub struct Listener {
57    inner: Box<dyn InputTransformer + Send>,
58    sender: Sender<Log>,
59}
60
61impl Listener {
62    fn send(&mut self, le: Log) -> Result<()> {
63        block_on(self.sender.send(le))?;
64        Ok(())
65    }
66}
67
68impl InputTransformer for Listener {
69    fn transform(&mut self, ie: InputEvent) -> Option<Vec<ControlCode>> {
70        if let Err(e) = self.send(Log::In(ie)) {
71            error!("error sending: {:?}", e);
72        }
73        if let Some(vcc) = self.inner.transform(ie) {
74            for cc in vcc.iter() {
75                if let Err(e) = self.send(Log::Out(cc.clone())) {
76                    error!("error sending: {:?}", e);
77                }
78            }
79            return Some(vcc);
80        }
81        None
82    }
83}