use anyhow::{anyhow, Result};
use std::io::{BufReader, BufWriter, Read, Write};
use std::net::TcpStream;
use crate::device::ConnectedDevice;
use crate::performance::PerformanceOption;
use crate::request::Request;
use crate::response;
use crate::samplerate::SampleRate;
#[faux::create]
#[derive(Debug)]
pub struct Connection {
stream: TcpStream,
}
#[faux::methods]
impl Connection {
pub fn new(ip_port: &str) -> Self {
Self {
stream: TcpStream::connect(ip_port).unwrap(),
}
}
pub fn general_recieve_ack(&mut self) -> Result<bool> {
let r: String = std::str::from_utf8(&self.read_line()?)?.to_string();
Ok(response::verify_ack(&r))
}
pub fn general_recieve_message(&mut self) -> Result<String> {
let msg: String = std::str::from_utf8(&self.read_line()?)?.to_string();
response::verify_ack(&msg);
Ok(msg)
}
fn read_line(&mut self) -> Result<Vec<u8>> {
let mut reader = BufReader::new(&self.stream);
let mut buf = [0; 500];
let len = reader.read(&mut buf)?;
Ok(buf[..len].to_vec())
}
pub fn run_command(&mut self, command: &str) -> Result<()> {
let mut writer = BufWriter::new(&self.stream);
writer.write_all(command.as_bytes()).unwrap();
Ok(())
}
}
#[derive(Debug)]
pub struct Client {
connection: Connection,
}
impl Client {
pub fn new(connection: Connection) -> Result<Self> {
Ok(Self { connection })
}
}
impl Client {
pub fn set_num_samples(&mut self, num: u32) -> Result<bool> {
self.connection
.run_command(&format!("set_num_samples, {}\0", num))?;
Ok(self.connection.general_recieve_ack()?)
}
pub fn get_num_samples(&mut self) -> Result<u32> {
self.connection.run_command("get_num_samples\0")?;
let response = self.connection.general_recieve_message()?;
if response::verify_ack(&response) {
Ok(response::parse_num_samples(&response::remove_ack(
&response,
)))
} else {
Err(anyhow!("No ACK found"))
}
}
pub fn set_capture_seconds(&mut self, seconds: f32) -> Result<bool> {
self.connection
.run_command(&format!("set_capture_seconds, {}\0", seconds))?;
Ok(self.connection.general_recieve_ack()?)
}
pub fn set_sample_rate(&mut self, rate: &SampleRate) -> Result<bool> {
self.connection.run_command(&format!(
"set_sample_rate, {}, {}\0",
rate.DigitalSampleRate, rate.AnalogSampleRate
))?;
Ok(self.connection.general_recieve_ack()?)
}
pub fn get_sample_rate(&mut self) -> Result<SampleRate> {
self.connection.run_command("get_sample_rate\0")?;
let response = self.connection.general_recieve_message()?;
Ok(response::parse_get_sample_rate(&response::remove_ack(
&response,
)))
}
pub fn get_all_sample_rates(&mut self) -> Result<Vec<SampleRate>> {
self.connection.run_command("get_all_sample_rates\0")?;
let response = self.connection.general_recieve_message()?;
Ok(response::parse_get_all_sample_rates(&response::remove_ack(
&response,
)))
}
pub fn get_performance(&mut self) -> Result<u8> {
self.connection.run_command("get_performance\0")?;
let response = self.connection.general_recieve_message()?;
Ok(response::parse_performance(&response::remove_ack(
&response,
)))
}
pub fn set_performance(&mut self, perf: PerformanceOption) -> Result<bool> {
let input = String::from(&format!("set_performance, {}\0", perf as i32));
self.connection.run_command(&input)?;
Ok(self.connection.general_recieve_ack()?)
}
pub fn get_connected_devices(&mut self) -> Result<Vec<ConnectedDevice>> {
self.connection.run_command("get_connected_devices\0")?;
let response = self.connection.general_recieve_message()?;
Ok(response::parse_connected_devices(&response::remove_ack(
&response,
)))
}
pub fn select_active_device(&mut self, device: ConnectedDevice) -> Result<bool> {
let b = self
.get_connected_devices()
.unwrap()
.into_iter()
.position(|a| a == device);
self.connection
.run_command(&format!("select_active_device, {}", b.unwrap() + 1))?;
Ok(true)
}
pub fn get_active_device(&mut self) -> Result<ConnectedDevice> {
self.connection.run_command("get_connected_devices\0")?;
let response = self.connection.general_recieve_message()?;
Ok(
response::parse_connected_devices(&response::remove_ack(&response))
.into_iter()
.find(|a| a.is_active)
.unwrap(),
)
}
pub fn get_active_channels(&mut self) -> Result<Vec<Vec<u8>>> {
self.connection.run_command("get_active_channels\0")?;
let response = self.connection.general_recieve_message()?;
Ok(response::parse_get_active_channels(&response::remove_ack(
&response,
))?)
}
pub fn set_active_channels(
&mut self,
digital_channels: &[u8],
analog_channels: &[u8],
) -> Result<bool> {
self.connection
.run_command(&Request::prepare_set_active_channels(
digital_channels,
analog_channels,
)?)?;
Ok(self.connection.general_recieve_ack()?)
}
pub fn reset_active_channels(&mut self) -> Result<bool> {
self.connection.run_command("reset_active_channels\0")?;
Ok(self.connection.general_recieve_ack()?)
}
pub fn start_capture(&mut self) -> Result<bool> {
self.connection.run_command("capture\0")?;
Ok(true)
}
pub fn start_capture_block_until_finished(&mut self) -> Result<bool> {
self.start_capture()?;
Ok(self.connection.general_recieve_ack()?)
}
pub fn is_processing_complete(&mut self) -> Result<bool> {
self.connection.run_command("is_processing_complete\0")?;
let response = self.connection.general_recieve_message()?;
Ok(response::parse_processing_complete(&response::remove_ack(
&response,
)))
}
pub fn stop_capture(&mut self) -> Result<bool> {
self.connection.run_command("stop_capture\0")?;
Ok(self.connection.general_recieve_ack()?)
}
pub fn close_all_tabs(&mut self) -> Result<bool> {
self.connection.run_command("close_all_tabs\0")?;
Ok(self.connection.general_recieve_ack()?)
}
}