Skip to main content

stynx_code_bridge/infrastructure/
stdio_transport.rs

1use std::io::{self, BufRead, Write};
2use stynx_code_errors::AppResult;
3use crate::domain::bridge_types::BridgeMessage;
4use crate::application::bridge_messaging::BridgeMessageHandler;
5
6pub struct StdioTransport;
7
8impl StdioTransport {
9    pub fn new() -> Self {
10        Self
11    }
12
13    pub async fn run<H: BridgeMessageHandler>(&self, handler: H) -> AppResult<()> {
14        let stdin = io::stdin();
15        let stdout = io::stdout();
16
17        for line in stdin.lock().lines() {
18            let line = line.map_err(|e| stynx_code_errors::AppError::Internal(anyhow::anyhow!(e)))?;
19            if line.trim().is_empty() {
20                continue;
21            }
22
23            let msg: BridgeMessage = match serde_json::from_str(&line) {
24                Ok(m) => m,
25                Err(e) => {
26                    tracing::warn!(?e, "failed to parse message");
27                    continue;
28                }
29            };
30
31            let response = handler.handle_message(msg).await?;
32            let mut out = stdout.lock();
33            let serialized = serde_json::to_string(&response)
34                .map_err(|e| stynx_code_errors::AppError::Internal(anyhow::anyhow!(e)))?;
35            writeln!(out, "{}", serialized)
36                .map_err(|e| stynx_code_errors::AppError::Internal(anyhow::anyhow!(e)))?;
37        }
38
39        Ok(())
40    }
41}
42
43impl Default for StdioTransport {
44    fn default() -> Self {
45        Self::new()
46    }
47}