Working connection and display of info
This commit is contained in:
parent
a7b3ecf178
commit
a667c6d98b
3
.cargo/config.toml
Normal file
3
.cargo/config.toml
Normal file
@ -0,0 +1,3 @@
|
||||
|
||||
[build]
|
||||
rustflags = ["--cfg", "tokio_unstable"]
|
3
.gitignore
vendored
3
.gitignore
vendored
@ -1 +1,4 @@
|
||||
/target
|
||||
/vendor
|
||||
/Cargo.lock
|
||||
.vscode/launch.json
|
||||
|
1379
Cargo.lock
generated
1379
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -22,11 +22,16 @@ pki-types = { package = "rustls-pki-types", version = "1.0", features = [
|
||||
tokio-rustls = { version = "0.25" }
|
||||
env_logger = "0.10.1"
|
||||
log = "0.4.20"
|
||||
tokio = { version = "1.34.0", features = ["full"] }
|
||||
tokio = { version = "1.34.0", features = ["full", "tracing"] }
|
||||
webpki-roots = "0.26.0"
|
||||
nom = "7.1.3"
|
||||
managesieve = { path = "../managesieve" }
|
||||
anyhow = "1.0"
|
||||
thiserror = "1.0"
|
||||
gtk4 = { version = "0.7.3", features = ["gnome_45"] }
|
||||
gtk4 = { version = "0.7", features = ["gnome_45", "blueprint"] }
|
||||
serde = { version = "1.0.193", features = ["derive"] }
|
||||
libadwaita = { version = "0.5.3", features = ["gtk_v4_10", "v1_4"] }
|
||||
gtk-blueprint = "0.2"
|
||||
phf = "0.11"
|
||||
tracing = "0.1"
|
||||
console-subscriber = "0.2"
|
||||
|
3
build.rs
Normal file
3
build.rs
Normal file
@ -0,0 +1,3 @@
|
||||
fn main() {
|
||||
println!("cargo:rerun-if-changed=**/*.blp");
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
|
||||
<!DOCTYPE cambalache-project SYSTEM "cambalache-project.dtd">
|
||||
<cambalache-project version="0.13.1" target_tk="gtk-4.0">
|
||||
<ui>
|
||||
(1,None,"sieverman.ui","sieverman.ui",None,None,"Franz Dietrich",None,None,None,None)
|
||||
</ui>
|
||||
<object>
|
||||
(1,1,"GtkApplicationWindow","sieverman",None,None,None,None,-1,None),
|
||||
(1,2,"GtkBox",None,1,None,None,None,-1,None),
|
||||
(1,3,"GtkBox",None,2,None,None,None,1,None),
|
||||
(1,4,"GtkActionBar",None,2,None,None,None,None,None),
|
||||
(1,5,"GtkStatusbar",None,2,None,None,None,2,None),
|
||||
(1,6,"GtkSpinner",None,3,None,None,None,1,None),
|
||||
(1,7,"GtkLabel","messages",3,None,None,None,None,None),
|
||||
(1,9,"GtkFrame",None,3,None,None,None,2,None),
|
||||
(1,10,"GtkLabel","serverstatus_2",9,None,None,None,None,None)
|
||||
</object>
|
||||
<object_property>
|
||||
(1,2,"GtkOrientable","orientation","vertical",None,None,None,None,None,None,None,None,None),
|
||||
(1,3,"GtkBox","baseline-child","0",None,None,None,None,None,None,None,None,None),
|
||||
(1,3,"GtkBox","homogeneous","True",None,None,None,None,None,None,None,None,None),
|
||||
(1,6,"GtkSpinner","spinning","True",None,None,None,None,None,None,None,None,None),
|
||||
(1,7,"GtkLabel","label","Loading",None,None,None,None,None,None,None,None,None),
|
||||
(1,10,"GtkLabel","label","Loading…",None,None,None,None,None,None,None,None,None)
|
||||
</object_property>
|
||||
<object_data>
|
||||
(1,3,"GtkWidget",1,1,None,None,None,None,None,None),
|
||||
(1,3,"GtkWidget",2,2,None,1,None,None,None,None),
|
||||
(1,3,"GtkWidget",2,3,None,1,None,None,None,None),
|
||||
(1,3,"GtkWidget",2,4,None,1,None,None,None,None),
|
||||
(1,3,"GtkWidget",2,5,None,1,None,None,None,None),
|
||||
(1,3,"GtkWidget",2,6,None,1,None,None,None,None),
|
||||
(1,3,"GtkWidget",2,7,None,1,None,None,None,None),
|
||||
(1,3,"GtkWidget",2,8,None,1,None,None,None,None)
|
||||
</object_data>
|
||||
</cambalache-project>
|
45
gui/main_window.blp
Normal file
45
gui/main_window.blp
Normal file
@ -0,0 +1,45 @@
|
||||
using Gtk 4.0;
|
||||
using Adw 1;
|
||||
|
||||
Adw.ApplicationWindow window {
|
||||
default-width: 900;
|
||||
default-height: 500;
|
||||
|
||||
content: Gtk.Box {
|
||||
orientation: vertical;
|
||||
|
||||
Adw.HeaderBar{
|
||||
title-widget: Adw.WindowTitle {
|
||||
title: "Sieverman";
|
||||
};
|
||||
|
||||
Gtk.Button { label: "Neu";}
|
||||
}
|
||||
Gtk.Box {
|
||||
orientation: horizontal;
|
||||
|
||||
vexpand: true;
|
||||
halign: fill;
|
||||
|
||||
Gtk.Label{
|
||||
label: "Log information";
|
||||
hexpand: true;
|
||||
}
|
||||
Gtk.ScrolledWindow server_info {
|
||||
width-request: 100;
|
||||
Adw.PreferencesPage {
|
||||
Adw.PreferencesGroup server_settings{
|
||||
vexpand: true;
|
||||
valign: center;
|
||||
title: "Server Information";
|
||||
description: "The information the server published on connection";
|
||||
}}
|
||||
|
||||
}
|
||||
}
|
||||
Gtk.Statusbar{Gtk.Label{
|
||||
label: "Status";
|
||||
}}
|
||||
|
||||
};
|
||||
}
|
12
gui/server_info_row.blp
Normal file
12
gui/server_info_row.blp
Normal file
@ -0,0 +1,12 @@
|
||||
using Gtk 4.0;
|
||||
using Adw 1;
|
||||
|
||||
|
||||
Adw.ActionRow server_info_row {
|
||||
title: "Server2";
|
||||
|
||||
|
||||
Gtk.Label server_info_row_value{
|
||||
label: "Stalwart";
|
||||
}}
|
||||
|
@ -1,41 +0,0 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<!-- Created with Cambalache 0.16.0 -->
|
||||
<interface>
|
||||
<!-- interface-name sieverman.ui -->
|
||||
<!-- interface-authors Franz Dietrich -->
|
||||
<requires lib="gtk" version="4.12"/>
|
||||
<object class="GtkApplicationWindow" id="sieverman">
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkActionBar"/>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="baseline-child">0</property>
|
||||
<property name="homogeneous">True</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="messages">
|
||||
<property name="label">Loading</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSpinner">
|
||||
<property name="spinning">True</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="serverstatus">
|
||||
<property name="label">Loading…</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStatusbar"/>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
@ -1,36 +1,29 @@
|
||||
use log::{info, trace};
|
||||
use sieverman::ConnectionInfo;
|
||||
use tracing::info;
|
||||
|
||||
use crate::protocol::BackToFront;
|
||||
|
||||
pub(crate) async fn run(
|
||||
to_frontend_tx: tokio::sync::mpsc::Sender<BackToFront>,
|
||||
) -> anyhow::Result<()> {
|
||||
trace!("Starting up sieverman…");
|
||||
info!("Starting up sieverman…");
|
||||
info!("Creating connection info");
|
||||
let info = ConnectionInfo::new("teilgedanken.de", 4190);
|
||||
let mut connected = info.connect().await.unwrap();
|
||||
info!("connected to the server");
|
||||
loop {
|
||||
match connected.read_introduction().await {
|
||||
Ok(sieverman::IsComplete::Yes(c)) => {
|
||||
connected = c;
|
||||
break;
|
||||
}
|
||||
Ok(sieverman::IsComplete::No(c)) => {
|
||||
trace!("Incomplete data waiting for some time…");
|
||||
connected = c
|
||||
}
|
||||
Err(e) => return Err(anyhow::anyhow!("something went wrong: {}", e)),
|
||||
};
|
||||
tokio::time::sleep(std::time::Duration::from_millis(100)).await;
|
||||
connected.log_buffer().await;
|
||||
}
|
||||
trace!("Fully read the introduction:");
|
||||
connected.log_buffer().await;
|
||||
connected.log_server_settings().await;
|
||||
info!("connecting…");
|
||||
let future_info = info.connect();
|
||||
info!("waiting for the connection to be established");
|
||||
let mut connected = match future_info.await {
|
||||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
info!("Failed to connect: {:?}", e);
|
||||
panic!("Something went wrong");
|
||||
}
|
||||
};
|
||||
|
||||
info!("Fully read the introduction:");
|
||||
to_frontend_tx
|
||||
.send(BackToFront::ServerConnected(
|
||||
connected.get_server_capabilities(),
|
||||
connected.get_server_capabilities().clone(),
|
||||
))
|
||||
.await
|
||||
.unwrap();
|
||||
|
@ -1,11 +1,14 @@
|
||||
use std::{cell::RefCell, fmt::Display, rc::Rc};
|
||||
use std::{cell::RefCell, rc::Rc};
|
||||
|
||||
use crate::__COMPILED_BLUEPRINT_MAP__;
|
||||
use gtk4::{
|
||||
glib,
|
||||
prelude::{ApplicationExt, BoxExt, GtkWindowExt, WidgetExt},
|
||||
Application, ApplicationWindow, Builder, Label,
|
||||
prelude::{ApplicationExt, GtkWindowExt},
|
||||
Application,
|
||||
};
|
||||
use log::trace;
|
||||
use gtk_blueprint::get_blp;
|
||||
use libadwaita::prelude::{PreferencesGroupExt, PreferencesRowExt};
|
||||
use tracing::trace;
|
||||
|
||||
use crate::protocol::BackToFront;
|
||||
|
||||
@ -25,50 +28,30 @@ fn build_ui(
|
||||
app: >k4::Application,
|
||||
from_backend_rx: Rc<RefCell<Option<tokio::sync::mpsc::Receiver<BackToFront>>>>,
|
||||
) {
|
||||
let action_content_status = gtk4::Box::builder()
|
||||
.orientation(gtk4::Orientation::Vertical)
|
||||
.spacing(5)
|
||||
.build();
|
||||
let action = gtk4::ActionBar::new();
|
||||
let status = gtk4::Statusbar::new();
|
||||
let main_log_server_info = gtk4::Box::builder()
|
||||
.orientation(gtk4::Orientation::Horizontal)
|
||||
.hexpand(true)
|
||||
.vexpand(true)
|
||||
.halign(gtk4::Align::Fill)
|
||||
.build();
|
||||
action_content_status.append(&action);
|
||||
action_content_status.append(&main_log_server_info);
|
||||
action_content_status.append(&status);
|
||||
let log = gtk4::Label::builder().label("Log").hexpand(true).build();
|
||||
let server_info_content = gtk4::Label::builder().label("Server Info").build();
|
||||
let server_info_container = gtk4::ScrolledWindow::builder()
|
||||
.child(&server_info_content)
|
||||
.width_request(400)
|
||||
.build();
|
||||
main_log_server_info.append(&log);
|
||||
main_log_server_info.append(&server_info_container);
|
||||
let main_window = gtk4::ApplicationWindow::builder()
|
||||
.application(app)
|
||||
.title("Sieverman")
|
||||
.height_request(400)
|
||||
.width_request(400)
|
||||
.child(&action_content_status)
|
||||
.build();
|
||||
main_window.present();
|
||||
|
||||
let server_info = Rc::new(RefCell::new(server_info_content));
|
||||
let builder = gtk4::Builder::new();
|
||||
builder
|
||||
.add_from_string(get_blp!("gui/main_window.blp"))
|
||||
.expect("Failed to parse blueprint");
|
||||
let main_window = builder
|
||||
.object::<libadwaita::ApplicationWindow>("window")
|
||||
.unwrap();
|
||||
let prefrences_group = builder
|
||||
.object::<libadwaita::PreferencesGroup>("server_settings")
|
||||
.unwrap();
|
||||
main_window.set_application(Some(app));
|
||||
|
||||
let future = {
|
||||
let mut data_event_receiver = from_backend_rx.take().expect("data_event_reciver");
|
||||
async move {
|
||||
while let Some(event) = data_event_receiver.recv().await {
|
||||
trace!("data event: {:?}", event);
|
||||
match event {
|
||||
BackToFront::ServerConnected(message) => {
|
||||
server_info
|
||||
.borrow_mut()
|
||||
.set_label(&format!("{:#?}", message));
|
||||
BackToFront::ServerConnected(caps) => {
|
||||
prefrences_group.add(&row_in_settings("Greeting", &caps.implementation));
|
||||
prefrences_group
|
||||
.add(&row_in_settings("Authentication", &caps.sasl.join(",")));
|
||||
prefrences_group
|
||||
.add(&row_in_settings("Starttls", &caps.starttls.to_string()));
|
||||
prefrences_group.add(&row_in_settings("Version", &caps.version));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -78,4 +61,22 @@ fn build_ui(
|
||||
let c = glib::MainContext::default();
|
||||
c.spawn_local(future);
|
||||
main_window.present();
|
||||
trace!("Window is visible");
|
||||
}
|
||||
|
||||
fn row_in_settings(name: &str, value: &str) -> libadwaita::ActionRow {
|
||||
let builder = gtk4::Builder::new();
|
||||
builder
|
||||
.add_from_string(get_blp!("gui/server_info_row.blp"))
|
||||
.expect("Failed to parse blueprint");
|
||||
|
||||
let row = builder
|
||||
.object::<libadwaita::ActionRow>("server_info_row")
|
||||
.unwrap();
|
||||
row.set_title(name);
|
||||
let label = builder
|
||||
.object::<gtk4::Label>("server_info_row_value")
|
||||
.unwrap();
|
||||
label.set_label(value);
|
||||
row
|
||||
}
|
||||
|
48
src/bin/old/bluep_test.rs
Normal file
48
src/bin/old/bluep_test.rs
Normal file
@ -0,0 +1,48 @@
|
||||
use gtk4::prelude::{ApplicationExt, ApplicationExtManual, GtkWindowExt};
|
||||
// We're using gtk-builder feature here
|
||||
use gtk_blueprint::get_blp;
|
||||
use libadwaita::prelude::PreferencesGroupExt;
|
||||
|
||||
gtk_blueprint::gen_blp_map!("gui");
|
||||
fn main() {
|
||||
gtk4::init().expect("GTK initialization failed");
|
||||
libadwaita::init().expect("Adwaita initialization failed");
|
||||
|
||||
// Create app
|
||||
let application = gtk4::Application::builder()
|
||||
.application_id("de.teilgedanken.sieverman")
|
||||
.build();
|
||||
// Init app window and show it
|
||||
application.connect_activate(|app| {
|
||||
// You also can parse blueprint with Parser::parse
|
||||
// and then use it in gtk4::Builder
|
||||
let builder = gtk4::Builder::new();
|
||||
builder
|
||||
.add_from_string(get_blp!("gui/main_window.blp"))
|
||||
.expect("Failed to parse blueprint");
|
||||
|
||||
let window = builder
|
||||
.object::<libadwaita::ApplicationWindow>("window")
|
||||
.unwrap();
|
||||
|
||||
let settings: libadwaita::PreferencesGroup = builder
|
||||
.object("server_settings")
|
||||
.expect("get server settings");
|
||||
for _ in 0..5 {
|
||||
let builder = gtk4::Builder::new();
|
||||
builder
|
||||
.add_from_string(get_blp!("gui/headerbar.blp"))
|
||||
.expect("Failed to parse blueprint");
|
||||
let widget: libadwaita::PreferencesRow = builder
|
||||
.object("server_info_row")
|
||||
.expect("Couldn't get widget");
|
||||
settings.add(&widget);
|
||||
}
|
||||
|
||||
window.set_application(Some(app));
|
||||
window.present();
|
||||
});
|
||||
|
||||
// Run app
|
||||
application.run();
|
||||
}
|
@ -1,4 +1,3 @@
|
||||
use log::info;
|
||||
use nom::branch::alt;
|
||||
use nom::bytes::complete::is_not;
|
||||
use nom::character::is_space;
|
||||
@ -12,6 +11,7 @@ use nom::{character, number};
|
||||
use sieverman::parser::parse_server_config;
|
||||
use sieverman::{Methods, ServerSettings};
|
||||
use std::error::Error;
|
||||
use tracing::info;
|
||||
|
||||
fn main() -> Result<(), Box<dyn Error>> {
|
||||
env_logger::init();
|
@ -9,7 +9,6 @@
|
||||
/// that is sensible outside of example code.
|
||||
use std::sync::Arc;
|
||||
|
||||
use log::{error, info, trace};
|
||||
use managesieve::{Capability, MSResult, Response};
|
||||
use nom::{error::ParseError, IResult};
|
||||
use sieverman::parser::parse_server_config;
|
||||
@ -23,6 +22,7 @@ use tokio_rustls::{
|
||||
rustls::{ClientConfig, KeyLogFile, RootCertStore},
|
||||
TlsConnector,
|
||||
};
|
||||
use tracing::{error, info, trace};
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! parse_response {
|
@ -1,7 +1,7 @@
|
||||
use managesieve::Capability;
|
||||
use managesieve::Capabilities;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
pub enum BackToFront {
|
||||
ServerConnected(Vec<Capability>),
|
||||
ServerConnected(Capabilities),
|
||||
}
|
||||
|
@ -1,15 +1,27 @@
|
||||
mod backend;
|
||||
mod gui;
|
||||
pub mod protocol;
|
||||
use std::{cell::RefCell, rc::Rc, thread};
|
||||
use std::{cell::RefCell, rc::Rc, thread, time::Duration};
|
||||
|
||||
use gtk4::{glib, prelude::ApplicationExtManual as _};
|
||||
use tracing::{info, trace};
|
||||
|
||||
gtk_blueprint::gen_blp_map!("gui");
|
||||
|
||||
fn main() -> glib::ExitCode {
|
||||
env_logger::init();
|
||||
console_subscriber::ConsoleLayer::builder()
|
||||
// set how long the console will retain data from completed tasks
|
||||
.retention(Duration::from_secs(60))
|
||||
// set the address the server is bound to
|
||||
.server_addr(([127, 0, 0, 1], 6669))
|
||||
.init();
|
||||
|
||||
gtk4::init().expect("Failed to initialize GTK");
|
||||
libadwaita::init().expect("Adwaita initialization failed");
|
||||
|
||||
let (to_frontent_tx, from_backend_rx) = tokio::sync::mpsc::channel(5);
|
||||
let _handle = thread::spawn(move || {
|
||||
info!("Running Backend");
|
||||
tokio::runtime::Builder::new_current_thread()
|
||||
.enable_io()
|
||||
.enable_time()
|
||||
@ -21,5 +33,8 @@ fn main() -> glib::ExitCode {
|
||||
|
||||
let app = gui::main_window::get_app(Rc::new(RefCell::new(Some(from_backend_rx))));
|
||||
|
||||
app.run()
|
||||
let res = app.run();
|
||||
trace!("End");
|
||||
|
||||
res
|
||||
}
|
||||
|
95
src/lib.rs
95
src/lib.rs
@ -1,20 +1,18 @@
|
||||
use std::{any, net::SocketAddr, sync::Arc, time::Duration};
|
||||
use std::{sync::Arc, time::Duration};
|
||||
|
||||
use log::{error, info, trace};
|
||||
use managesieve::Capability;
|
||||
use std::net::ToSocketAddrs;
|
||||
use managesieve::Capabilities;
|
||||
use thiserror::Error;
|
||||
use tokio::{
|
||||
io::{split, AsyncBufReadExt, BufReader, ReadHalf, WriteHalf},
|
||||
io::{split, AsyncBufReadExt, BufReader, WriteHalf},
|
||||
net::TcpStream,
|
||||
sync::Mutex,
|
||||
task::JoinHandle,
|
||||
};
|
||||
use tokio_rustls::{
|
||||
client::TlsStream,
|
||||
rustls::{ClientConfig, KeyLogFile, RootCertStore},
|
||||
TlsConnector,
|
||||
};
|
||||
use tracing::{error, info, trace};
|
||||
|
||||
pub mod parser;
|
||||
|
||||
@ -32,6 +30,7 @@ impl ConnectionInfo {
|
||||
}
|
||||
}
|
||||
pub async fn connect(self) -> Result<ConnectionConnected, anyhow::Error> {
|
||||
info!("connecting to the server");
|
||||
trace!("Building Cert Store");
|
||||
let mut root_store = RootCertStore::empty();
|
||||
root_store.extend(webpki_roots::TLS_SERVER_ROOTS.iter().cloned());
|
||||
@ -48,11 +47,11 @@ impl ConnectionInfo {
|
||||
let domain = pki_types::ServerName::try_from(self.domain.clone())?.to_owned();
|
||||
trace!("Attach the connector");
|
||||
let stream = connector.connect(domain, stream).await?;
|
||||
let (reader, mut writer) = split(stream);
|
||||
let (reader, writer) = split(stream);
|
||||
let buffer = Arc::new(Mutex::new(String::new()));
|
||||
let spawned_buffer = buffer.clone();
|
||||
|
||||
let join_handle = tokio::spawn(async move {
|
||||
let _join_handle = tokio::spawn(async move {
|
||||
let mut buf = String::new();
|
||||
let mut reader = BufReader::new(reader);
|
||||
loop {
|
||||
@ -67,13 +66,36 @@ impl ConnectionInfo {
|
||||
}
|
||||
buf.clear();
|
||||
};
|
||||
tokio::time::sleep(Duration::from_millis(50)).await;
|
||||
}
|
||||
});
|
||||
|
||||
let caps = loop {
|
||||
let mut buf = buffer.lock().await;
|
||||
trace!("reading new input:\n{}", buf);
|
||||
match managesieve::response_capability(&buf.to_string()) {
|
||||
Ok((rest, caps, resp)) => match resp.tag {
|
||||
managesieve::OkNoBye::Ok => {
|
||||
buf.clear();
|
||||
buf.push_str(rest);
|
||||
info!("Read the introduction");
|
||||
break caps;
|
||||
}
|
||||
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;
|
||||
};
|
||||
trace!("Capabilities read: {:#?}", &caps);
|
||||
Ok(ConnectionConnected {
|
||||
info: self,
|
||||
writer: Arc::new(writer), //server_settings: todo!(),
|
||||
writer: Arc::new(writer),
|
||||
buffer,
|
||||
server_settings: Vec::new(), //join_handle: Arc::new(join_handle),
|
||||
server_settings: caps,
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -85,7 +107,7 @@ pub struct ConnectionConnected {
|
||||
writer: Arc<WriteHalf<TlsStream<TcpStream>>>,
|
||||
buffer: Arc<Mutex<String>>,
|
||||
//pub join_handle: Arc<JoinHandle<()>>,
|
||||
server_settings: Vec<Capability>,
|
||||
server_settings: Capabilities,
|
||||
}
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
@ -95,7 +117,7 @@ pub enum ReadError {
|
||||
#[error("The data the server responded was invalid")]
|
||||
InvalidResponse(#[source] managesieve::Error),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum IsComplete<T> {
|
||||
Yes(T),
|
||||
No(T),
|
||||
@ -103,11 +125,12 @@ pub enum IsComplete<T> {
|
||||
|
||||
impl ConnectionConnected {
|
||||
pub async fn log_buffer(&self) {
|
||||
trace!("Buffer is: \n{}", self.buffer.lock().await)
|
||||
info!("Buffer is: \n{}", self.buffer.lock().await)
|
||||
}
|
||||
pub async fn log_server_settings(&self) {
|
||||
trace!("Serversettings:\n{:?}", self.server_settings)
|
||||
info!("Serversettings:\n{:?}", self.server_settings)
|
||||
}
|
||||
#[tracing::instrument(name = "gettin the intro")]
|
||||
pub async fn read_introduction(self) -> Result<IsComplete<Self>, anyhow::Error> {
|
||||
let Self {
|
||||
info,
|
||||
@ -116,12 +139,11 @@ impl ConnectionConnected {
|
||||
buffer,
|
||||
server_settings,
|
||||
} = self;
|
||||
tokio::time::sleep(Duration::from_millis(500)).await;
|
||||
tokio::time::sleep(Duration::from_millis(50)).await;
|
||||
let mut bf = buffer.lock().await;
|
||||
let bf_str = bf.clone();
|
||||
match managesieve::response_capability(&bf_str) {
|
||||
let response = match managesieve::response_capability(&bf.to_string()) {
|
||||
Ok((rest, capability, response)) => {
|
||||
trace!("{:?}", response);
|
||||
info!("Successfully read the introduction {:?}", response);
|
||||
bf.clear();
|
||||
bf.push_str(rest);
|
||||
drop(bf);
|
||||
@ -132,12 +154,15 @@ impl ConnectionConnected {
|
||||
server_settings: capability,
|
||||
}))
|
||||
}
|
||||
Err(managesieve::Error::IncompleteResponse) => Ok(IsComplete::No(Self {
|
||||
info,
|
||||
writer,
|
||||
buffer: buffer.clone(),
|
||||
server_settings,
|
||||
})),
|
||||
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)?
|
||||
@ -146,18 +171,20 @@ impl ConnectionConnected {
|
||||
error!("invalid input");
|
||||
Err(managesieve::Error::InvalidResponse)?
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn get_greeting(&self) -> Option<String> {
|
||||
for c in self.server_settings.iter() {
|
||||
if let Capability::Implementation(s) = c {
|
||||
return Some(s.clone());
|
||||
Err(managesieve::Error::MissingLine(line)) => {
|
||||
error!("a capability line was missing: {:?}", line);
|
||||
Err(managesieve::Error::InvalidResponse)?
|
||||
}
|
||||
}
|
||||
None
|
||||
};
|
||||
|
||||
response
|
||||
}
|
||||
pub fn get_server_capabilities(&self) -> Vec<Capability> {
|
||||
self.server_settings.clone()
|
||||
|
||||
pub fn get_greeting(&self) -> String {
|
||||
self.server_settings.implementation.to_string()
|
||||
}
|
||||
pub fn get_server_capabilities(&self) -> &Capabilities {
|
||||
&self.server_settings
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
use log::{info, trace};
|
||||
use nom::{
|
||||
branch::alt,
|
||||
bytes::complete::is_not,
|
||||
@ -11,6 +10,7 @@ use nom::{
|
||||
sequence::preceded,
|
||||
IResult,
|
||||
};
|
||||
use tracing::trace;
|
||||
|
||||
use crate::{parser::utils::key_value, Methods, ServerSettings};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user