mod envelope;
pub mod framing;
mod stdio;
use std::future::Future;
use std::io;
use thiserror::Error;
use crate::raw::RawMessage;
use crate::server::LanguageServer;
pub use stdio::StdioTransport;
#[derive(Debug, Error)]
pub enum TransportError {
#[error("io error: {0}")]
Io(#[from] io::Error),
#[error("connection closed by peer")]
Closed,
#[error("malformed message: {0}")]
Malformed(String),
#[error("message exceeds size limit ({length} > {limit} bytes)")]
OversizedMessage { length: usize, limit: usize },
#[error("serialization error: {0}")]
Serde(#[from] serde_json::Error),
}
pub trait Transport: Send + 'static {
fn recv(
&mut self,
) -> impl Future<Output = std::result::Result<RawMessage, TransportError>> + Send;
fn send(
&mut self,
msg: RawMessage,
) -> impl Future<Output = std::result::Result<(), TransportError>> + Send;
fn shutdown(self) -> impl Future<Output = std::result::Result<(), TransportError>> + Send;
}
pub fn stdio<S: LanguageServer>(server: S) -> StdioBuilder<S> {
StdioBuilder { server }
}
pub struct StdioBuilder<S> {
server: S,
}
impl<S: LanguageServer> StdioBuilder<S> {
pub async fn serve(self) -> crate::Result<()> {
let transport = StdioTransport::new();
crate::dispatcher::run(self.server, transport).await
}
}