1use std::io;
2
3use serde::Deserialize;
4use tokio::io::{AsyncBufReadExt, BufReader};
5use tokio::process::ChildStdout;
6
7use crate::agda::ReplState;
8use crate::debug::debug_response;
9use crate::resp::Resp;
10
11pub fn deserialize_agda<'a, T: Deserialize<'a>>(buf: &'a str) -> serde_json::Result<T> {
13 let buf = buf.trim_start_matches("JSON>").trim();
14 serde_json::from_str(buf)
15}
16
17pub struct AgdaRead {
18 buf: String,
19 agda: BufReader<ChildStdout>,
20}
21
22impl From<BufReader<ChildStdout>> for AgdaRead {
23 fn from(agda: BufReader<ChildStdout>) -> Self {
24 Self {
25 agda,
26 buf: String::with_capacity(2048),
27 }
28 }
29}
30
31impl From<ChildStdout> for AgdaRead {
32 fn from(o: ChildStdout) -> Self {
33 From::from(BufReader::new(o))
34 }
35}
36
37impl AgdaRead {
38 pub async fn response(&mut self) -> io::Result<Resp> {
40 self.agda.read_line(&mut self.buf).await?;
41 unsafe { debug_response(format!("[RES]: {}\n", self.buf)) };
42 let resp = deserialize_agda(&self.buf)?;
43 self.buf.clear();
44 Ok(resp)
45 }
46}
47
48impl ReplState {
49 pub async fn response(&mut self) -> io::Result<Resp> {
51 self.agda.response().await
52 }
53}