@@ -7,7 +7,8 @@ use serde_json::{from_value, to_value, Value};
77use std::process::Stdio;
88use std::sync::atomic::{AtomicU64, Ordering};
99use tokio::{
10− io::{BufReader, BufWriter},
10+ io::{AsyncBufRead, AsyncWrite, BufReader, BufWriter},
11+ net::TcpStream,
1112 process::{Child, Command},
1213 sync::mpsc::{channel, UnboundedReceiver, UnboundedSender},
1314};
@@ -257,7 +258,7 @@ struct VariablesResponseBody {
257258#[derive(Debug)]
258259pub struct Client {
259260 id: usize,
260− _process: Child,
261+ _process: Option<Child>,
261262 server_tx: UnboundedSender<Request>,
262263 server_rx: UnboundedReceiver<Payload>,
263264 request_counter: AtomicU64,
@@ -265,7 +266,33 @@ pub struct Client {
265266}
266267
267268impl Client {
268− pub fn start(cmd: &str, args: Vec<&str>, id: usize) -> Result<Self> {
269+ pub fn streams(
270+ rx: Box<dyn AsyncBufRead + Unpin + Send>,
271+ tx: Box<dyn AsyncWrite + Unpin + Send>,
272+ id: usize,
273+ process: Option<Child>,
274+ ) -> Result<Self> {
275+ let (server_rx, server_tx) = Transport::start(rx, tx, id);
276+
277+ let client = Self {
278+ id,
279+ _process: process,
280+ server_tx,
281+ server_rx,
282+ request_counter: AtomicU64::new(0),
283+ capabilities: None,
284+ };
285+
286+ Ok(client)
287+ }
288+
289+ pub async fn tcp(addr: std::net::SocketAddr, id: usize) -> Result<Self> {
290+ let stream = TcpStream::connect(addr).await?;
291+ let (rx, tx) = stream.into_split();
292+ Self::streams(Box::new(BufReader::new(rx)), Box::new(tx), id, None)
293+ }
294+
295+ pub fn stdio(cmd: &str, args: Vec<&str>, id: usize) -> Result<Self> {
269296 let process = Command::new(cmd)
270297 .args(args)
271298 .stdin(Stdio::piped())
@@ -280,18 +307,12 @@ impl Client {
280307 let writer = BufWriter::new(process.stdin.take().expect("Failed to open stdin"));
281308 let reader = BufReader::new(process.stdout.take().expect("Failed to open stdout"));
282309
283− let (server_rx, server_tx) = Transport::start(Box::new(reader), Box::new(writer), id);
284−
285− let client = Self {
310+ Self::streams(
311+ Box::new(BufReader::new(reader)),
312+ Box::new(writer),
286313 id,
287− _process: process,
288− server_tx,
289− server_rx,
290− request_counter: AtomicU64::new(0),
291− capabilities: None,
292− };
293−
294− Ok(client)
314+ Some(process),
315+ )
295316 }
296317
297318 pub fn id(&self) -> usize {