create a first list_scripts command

This commit is contained in:
Franz Dietrich 2024-01-20 16:01:36 +01:00
parent f78f46b2f3
commit cad7822c16

View File

@ -1,9 +1,10 @@
use std::{sync::Arc, time::Duration};
use anyhow::Context;
use managesieve::Capabilities;
use thiserror::Error;
use tokio::{
io::{split, AsyncBufReadExt, BufReader, WriteHalf},
io::{split, AsyncBufReadExt, AsyncWriteExt, BufReader, WriteHalf},
net::TcpStream,
sync::Mutex,
};
@ -93,7 +94,7 @@ impl ConnectionInfo {
trace!("Capabilities read: {:#?}", &caps);
Ok(ConnectionConnected {
info: self,
writer: Arc::new(writer),
writer: Arc::new(Mutex::new(writer)),
buffer,
server_settings: caps,
})
@ -104,7 +105,7 @@ impl ConnectionInfo {
pub struct ConnectionConnected {
info: ConnectionInfo,
//reader: Arc<ReadHalf<TlsStream<TcpStream>>>,
writer: Arc<WriteHalf<TlsStream<TcpStream>>>,
writer: Arc<Mutex<WriteHalf<TlsStream<TcpStream>>>>,
buffer: Arc<Mutex<String>>,
//pub join_handle: Arc<JoinHandle<()>>,
server_settings: Capabilities,
@ -130,54 +131,51 @@ impl ConnectionConnected {
pub async fn log_server_settings(&self) {
info!("Serversettings:\n{:?}", self.server_settings)
}
#[tracing::instrument(name = "gettin the intro")]
pub async fn read_introduction(self) -> Result<IsComplete<Self>, anyhow::Error> {
pub async fn list_scripts(self) -> anyhow::Result<(Vec<(String, bool)>, Self)> {
let Self {
info,
//reader: Arc<ReadHalf<TlsStream<TcpStream>>>,
writer,
buffer,
info,
server_settings,
} = self;
tokio::time::sleep(Duration::from_millis(50)).await;
let mut bf = buffer.lock().await;
let response = match managesieve::response_capability(&bf.to_string()) {
Ok((rest, capability, response)) => {
info!("Successfully read the introduction {:?}", response);
bf.clear();
bf.push_str(rest);
drop(bf);
Ok(IsComplete::Yes(Self {
info,
writer: writer.clone(),
buffer: buffer.clone(),
server_settings: capability,
}))
}
Err(managesieve::Error::IncompleteResponse) => {
trace!("incomplete introduction");
Ok(IsComplete::No(Self {
info,
writer,
buffer: buffer.clone(),
server_settings,
}))
}
Err(managesieve::Error::InvalidResponse) => {
error!("invalid response");
Err(managesieve::Error::InvalidResponse)?
}
Err(managesieve::Error::InvalidInput) => {
error!("invalid input");
Err(managesieve::Error::InvalidResponse)?
}
Err(managesieve::Error::MissingLine(line)) => {
error!("a capability line was missing: {:?}", line);
Err(managesieve::Error::InvalidResponse)?
}
};
let command = managesieve::Command::list_scripts();
writer
.lock()
.await
.write_all(command.to_string().as_bytes())
.await
.context("Failed to write LISTSCRIPTS command")?;
response
let scriptslist = loop {
let mut buf = buffer.lock().await;
trace!("reading new input:\n{}", buf);
match managesieve::response_listscripts(&buf.to_string()) {
Ok((rest, scriptslist, resp)) => match resp.tag {
managesieve::OkNoBye::Ok => {
buf.clear();
buf.push_str(rest);
info!("Read the introduction");
break scriptslist;
}
managesieve::OkNoBye::No | managesieve::OkNoBye::Bye => {
trace!("Connection closed!");
//panic!("Invalid Response")
}
},
Err(e) => trace!("(temporary) error: {}", e),
}
tokio::time::sleep(Duration::from_millis(50)).await;
};
Ok((
scriptslist,
Self {
writer,
buffer,
info,
server_settings,
},
))
}
pub fn get_greeting(&self) -> String {