@@ -5,11 +5,18 @@ use crate::{
5use log::{error, info};
5use log::{error, info};
6use serde::{Deserialize, Serialize};
6use serde::{Deserialize, Serialize};
7use serde_json::{from_value, to_value, Value};
7use serde_json::{from_value, to_value, Value};
8−use std::sync::{
8+use std::{
10+ net::{IpAddr, Ipv4Addr},
9− atomic::{AtomicU64, Ordering},
16+ atomic::{AtomicU64, Ordering},
12−use std::{collections::HashMap, process::Stdio};
13use tokio::{
20use tokio::{
14 io::{AsyncBufRead, AsyncWrite, BufReader, BufWriter},
21 io::{AsyncBufRead, AsyncWrite, BufReader, BufWriter},
@@ -19,6 +26,7 @@ use tokio::{
19 mpsc::{channel, Receiver, Sender, UnboundedReceiver, UnboundedSender},
26 mpsc::{channel, Receiver, Sender, UnboundedReceiver, UnboundedSender},
24#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
32#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
@@ -376,6 +384,82 @@ impl Client {
376 Ok(client)
384 Ok(client)
387+ pub async fn tcp(addr: std::net::SocketAddr, id: usize) -> Result<Self> {
388+ let stream = TcpStream::connect(addr).await?;
389+ let (rx, tx) = stream.into_split();
390+ Self::streams(Box::new(BufReader::new(rx)), Box::new(tx), id, None)
393+ pub fn stdio(cmd: &str, args: Vec<&str>, id: usize) -> Result<Self> {
394+ let process = Command::new(cmd)
396+ .stdin(Stdio::piped())
397+ .stdout(Stdio::piped())
398+ // make sure the process is reaped on drop
402+ let mut process = process?;
404+ // TODO: do we need bufreader/writer here? or do we use async wrappers on unblock?
405+ let writer = BufWriter::new(process.stdin.take().expect("Failed to open stdin"));
406+ let reader = BufReader::new(process.stdout.take().expect("Failed to open stdout"));
409+ Box::new(BufReader::new(reader)),
416+ async fn get_port() -> Option<u16> {
418+ tokio::net::TcpListener::bind(SocketAddr::new(
419+ IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)),
430+ pub async fn tcp_process(
436+ let port = Self::get_port().await.unwrap();
438+ let process = Command::new(cmd)
440+ .args(port_format.replace("{}", &port.to_string()).split(' '))
441+ // make sure the process is reaped on drop
445+ // Wait for adapter to become ready for connection
446+ time::sleep(time::Duration::from_millis(500)).await;
448+ let stream = TcpStream::connect(SocketAddr::new(
449+ IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)),
454+ let (rx, tx) = stream.into_split();
456+ Box::new(BufReader::new(rx)),
379 async fn recv(
463 async fn recv(
380 awaited_events: Arc<Mutex<HashMap<String, Sender<Event>>>>,
464 awaited_events: Arc<Mutex<HashMap<String, Sender<Event>>>>,
381 mut server_rx: UnboundedReceiver<Payload>,
465 mut server_rx: UnboundedReceiver<Payload>,
@@ -413,35 +497,6 @@ impl Client {
416− pub async fn tcp(addr: std::net::SocketAddr, id: usize) -> Result<Self> {
417− let stream = TcpStream::connect(addr).await?;
418− let (rx, tx) = stream.into_split();
419− Self::streams(Box::new(BufReader::new(rx)), Box::new(tx), id, None)
422− pub fn stdio(cmd: &str, args: Vec<&str>, id: usize) -> Result<Self> {
423− let process = Command::new(cmd)
425− .stdin(Stdio::piped())
426− .stdout(Stdio::piped())
427− // make sure the process is reaped on drop
431− let mut process = process?;
433− // TODO: do we need bufreader/writer here? or do we use async wrappers on unblock?
434− let writer = BufWriter::new(process.stdin.take().expect("Failed to open stdin"));
435− let reader = BufReader::new(process.stdout.take().expect("Failed to open stdout"));
438− Box::new(BufReader::new(reader)),
445 pub fn id(&self) -> usize {
500 pub fn id(&self) -> usize {