stynx_code_bridge/infrastructure/
stdio_transport.rs1use 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}