diff options
Diffstat (limited to 'src/client.rs')
-rw-r--r-- | src/client.rs | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/src/client.rs b/src/client.rs new file mode 100644 index 0000000..492008a --- /dev/null +++ b/src/client.rs @@ -0,0 +1,50 @@ +use anyhow::{anyhow, bail, Result}; +use std::{ + io::{BufRead, BufReader, BufWriter, Write}, + net::{TcpStream, ToSocketAddrs}, +}; + +use crate::Serial; + +pub struct Client { + wsock: BufWriter<TcpStream>, + rsock: BufReader<TcpStream>, +} +impl Client { + pub fn new(address: impl ToSocketAddrs, secret: &str) -> Result<Self> { + let mut sock = TcpStream::connect(address)?; + writeln!(sock, "{secret}")?; + Ok(Self { + rsock: BufReader::new(sock.try_clone()?), + wsock: BufWriter::new(sock), + }) + } + pub fn list(&mut self) -> Result<Vec<(i64, u64, Serial)>> { + writeln!(self.wsock, "list")?; + self.wsock.flush()?; + let mut line = String::new(); + let mut out = Vec::new(); + loop { + self.rsock.read_line(&mut line)?; + if line.trim().is_empty() || line.ends_with("\n\n") { + break Ok(out); + } + check_error(&line)?; + let (mtime, rest) = line.trim().split_once(":").ok_or(anyhow!("size missing"))?; + let (size, serial) = rest.split_once(":").ok_or(anyhow!("serial missing"))?; + out.push((mtime.parse()?, size.parse()?, serial.parse()?)); + } + } + pub fn quit(mut self) -> Result<()> { + writeln!(self.wsock, "quit")?; + self.wsock.flush()?; + Ok(()) + } +} + +fn check_error(line: &str) -> Result<()> { + if let Some(message) = line.trim().strip_prefix("error") { + bail!("server error: {message}") + } + Ok(()) +} |