use color_eyre::{
Result,
eyre::{Context, bail},
};
use serde::Serialize;
use super::protocol::*;
use crate::{Error, PROTOCOL_VERSION, internal_prelude::*, message::*};
pub struct BlockingClient {
pub stream: GenericBlockingStream,
pub daemon_version: String,
}
impl std::fmt::Debug for BlockingClient {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Client")
.field("stream", &"GenericStream<not_debuggable>")
.finish()
}
}
impl BlockingClient {
pub fn new(
settings: ConnectionSettings<'_>,
secret: &[u8],
show_version_warning: bool,
) -> Result<Self> {
let mut stream = get_client_stream(settings).context("Failed to initialize stream.")?;
send_bytes(secret, &mut stream).context("Failed to send secret.")?;
let version_bytes = receive_bytes(&mut stream)
.context("Failed to receive version during handshake with daemon.")?;
if version_bytes.is_empty() {
bail!("Daemon went away after sending secret. Did you use the correct secret?")
}
let daemon_version = match String::from_utf8(version_bytes) {
Ok(version) => version,
Err(_) => {
bail!("Daemon sent invalid UTF-8. Did you use the correct secret?")
}
};
if daemon_version != PROTOCOL_VERSION && show_version_warning {
warn!(
"Different protocol version detected '{daemon_version}'. Consider updating and restarting the daemon."
);
}
Ok(BlockingClient {
stream,
daemon_version,
})
}
pub fn stream(&mut self) -> &mut GenericBlockingStream {
&mut self.stream
}
pub fn send_request<T>(&mut self, message: T) -> Result<(), Error>
where
T: Into<Request>,
T: Serialize + std::fmt::Debug,
{
send_message::<_, Request>(message, &mut self.stream)
}
pub fn receive_response(&mut self) -> Result<Response, Error> {
receive_message::<Response>(&mut self.stream)
}
pub fn daemon_version(&self) -> &String {
&self.daemon_version
}
}