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}