use crate::error::MCPError;
use serde::{de::DeserializeOwned, Serialize};
use std::io;
pub trait Transport {
fn send<T: Serialize>(&mut self, message: &T) -> Result<(), MCPError>;
fn receive<T: DeserializeOwned>(&mut self) -> Result<T, MCPError>;
}
#[cfg(feature = "async")]
pub trait AsyncTransport {
async fn send<T: Serialize>(&mut self, message: &T) -> Result<(), MCPError>;
async fn receive<T: DeserializeOwned>(&mut self) -> Result<T, MCPError>;
}
pub mod stdio {
use super::*;
use std::io::{BufRead, BufReader, Write};
pub struct StdioTransport {
reader: BufReader<Box<dyn io::Read>>,
writer: Box<dyn io::Write>,
}
impl Default for StdioTransport {
fn default() -> Self {
Self::new()
}
}
impl StdioTransport {
pub fn new() -> Self {
Self {
reader: BufReader::new(Box::new(io::stdin())),
writer: Box::new(io::stdout()),
}
}
pub fn with_reader_writer(reader: Box<dyn io::Read>, writer: Box<dyn io::Write>) -> Self {
Self {
reader: BufReader::new(reader),
writer,
}
}
}
impl Transport for StdioTransport {
fn send<T: Serialize>(&mut self, message: &T) -> Result<(), MCPError> {
let json = serde_json::to_string(message)?;
writeln!(self.writer, "{}", json).map_err(|e| MCPError::Transport(e.to_string()))?;
self.writer
.flush()
.map_err(|e| MCPError::Transport(e.to_string()))?;
Ok(())
}
fn receive<T: DeserializeOwned>(&mut self) -> Result<T, MCPError> {
let mut line = String::new();
self.reader
.read_line(&mut line)
.map_err(|e| MCPError::Transport(e.to_string()))?;
let message = serde_json::from_str(&line)?;
Ok(message)
}
}
}
pub mod websocket {
}