From 669f169a798fd742b6baec50fddf0155c7123f3b Mon Sep 17 00:00:00 2001 From: Ward from fusion-voyager-3 Date: Mon, 1 Jul 2024 00:23:36 +0300 Subject: [PATCH] expander rows --- .idea/workspace.xml | 4 +- Cargo.lock | 42 +++++++++++++++- Cargo.toml | 1 + src/apt_package_row/imp.rs | 48 +++++++++++++----- src/apt_package_row/mod.rs | 8 +-- src/apt_update/main.rs | 83 +++++++++++++++++++++++--------- src/apt_update_page/mod.rs | 63 +++++++++++++++--------- src/build_ui/mod.rs | 14 +++--- src/config.rs | 2 +- src/main.rs | 25 +++++----- src/pika_unixsocket_tools/lib.rs | 26 +++++++--- 11 files changed, 225 insertions(+), 91 deletions(-) diff --git a/.idea/workspace.xml b/.idea/workspace.xml index b5881f5..7a8cbd3 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -8,10 +8,7 @@ - - - diff --git a/Cargo.lock b/Cargo.lock index b862f56..9ec7e81 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -61,6 +61,17 @@ dependencies = [ "syn 2.0.68", ] +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi 0.1.19", + "libc", + "winapi 0.3.9", +] + [[package]] name = "autocfg" version = "1.3.0" @@ -509,6 +520,15 @@ dependencies = [ "system-deps", ] +[[package]] +name = "getopts" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5" +dependencies = [ + "unicode-width", +] + [[package]] name = "gimli" version = "0.29.0" @@ -767,6 +787,15 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + [[package]] name = "hermit-abi" version = "0.3.9" @@ -1033,7 +1062,7 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi", + "hermit-abi 0.3.9", "libc", ] @@ -1147,6 +1176,7 @@ dependencies = [ "futures 0.3.30", "gtk4", "libadwaita", + "pretty-bytes", "rust-apt", "rust-i18n", "serde", @@ -1173,6 +1203,16 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +[[package]] +name = "pretty-bytes" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "009d6edd2c1dbf2e1c0cd48a2f7766e03498d49ada7109a01c6911815c685316" +dependencies = [ + "atty", + "getopts", +] + [[package]] name = "proc-macro-crate" version = "1.3.1" diff --git a/Cargo.toml b/Cargo.toml index 7c73ed0..161895d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,3 +24,4 @@ serde = { version = "1.0.203", features = ["derive"] } serde_json = "1.0.118" async-trait = "0.1.80" futures = "0.3.30" +pretty-bytes = "0.2.2" diff --git a/src/apt_package_row/imp.rs b/src/apt_package_row/imp.rs index fe396ff..06ba8c7 100644 --- a/src/apt_package_row/imp.rs +++ b/src/apt_package_row/imp.rs @@ -6,6 +6,7 @@ use glib::{subclass::Signal, Properties, clone}; use gtk::{*}; use gtk::Orientation::Horizontal; use crate::apt_update_page::AptPackageSocket; +use pretty_bytes::converter::convert; use std::env; // ANCHOR: custom_button @@ -85,7 +86,7 @@ impl ObjectImpl for AptPackageRow { // create_prefix_content(&prefix_box, &package_name, &package_arch, &package_installed_version, &package_candidate_version); // - create_expandable_content(&expandable_box); + create_expandable_content(obj, &expandable_box, package_description, package_source_uri, package_maintainer, package_size, package_installed_size); })); obj.add_prefix(&prefix_box); @@ -246,7 +247,7 @@ fn create_prefix_content(prefix_box: >k::Box, package_name: &str ,package_arch prefix_box.append(&version_box); } -fn create_expandable_content(expandable_box: >k::Box) { +fn create_expandable_content(apt_package_row: &impl IsA, expandable_box: >k::Box, package_description: String, package_source_uri: String, package_maintainer: String, package_size: u64, package_installed_size: u64) { let expandable_page_selection_box = gtk::Box::builder() .orientation(Orientation::Horizontal) .hexpand(false) @@ -261,13 +262,17 @@ fn create_expandable_content(expandable_box: >k::Box) { expandable_page_selection_box.add_css_class("linked"); // let description_page_button = gtk::ToggleButton::builder() - .label(t!("changelog_page_button_label")) + .label(t!("description_page_button_label")) .active(true) .build(); let extra_info_page_button = gtk::ToggleButton::builder() .label(t!("extra_info_page_button_label")) .group(&description_page_button) .build(); + let uris_page_button = gtk::ToggleButton::builder() + .label(t!("uris_page_button_label")) + .group(&description_page_button) + .build(); let changelog_page_button = gtk::ToggleButton::builder() .label(t!("changelog_page_button_label")) // till we find a way to implement @@ -276,24 +281,45 @@ fn create_expandable_content(expandable_box: >k::Box) { .build(); expandable_page_selection_box.append(&description_page_button); expandable_page_selection_box.append(&extra_info_page_button); + expandable_page_selection_box.append(&uris_page_button); expandable_page_selection_box.append(&changelog_page_button); // expandable_box.append(&expandable_page_selection_box); // - let expandable_stack = gtk::Stack::builder() + let expandable_bin = adw::Bin::builder() .hexpand(true) .vexpand(true) - .vhomogeneous(true) - .hhomogeneous(true) - .transition_type(StackTransitionType::SlideLeftRight) .build(); // - expandable_box.append(&expandable_stack) + apt_package_row.connect_expanded_notify(clone!(@strong expandable_bin, @strong expandable_box, @strong apt_package_row, @strong description_page_button => move |apt_package_row| { + if apt_package_row.property("expanded") { + expandable_bin.set_child(Some(&extra_info_stack_page(&package_maintainer, package_size, package_installed_size))); + description_page_button.set_active(true); + expandable_box.append(&expandable_bin) + } else { + expandable_box.remove(&expandable_bin) + } + })); + //expandable_bin.add_named(&extra_info_stack_page(package_maintainer, package_size, package_installed_size), Some("extra_info_page")); + // } -fn extra_info_stack_page() { - //create_color_badge(t!("")) - //background-accent-bg +fn extra_info_stack_page(package_maintainer: &str, package_size: u64, package_installed_size: u64) -> gtk::Box { + let extra_info_badges_content_box = gtk::Box::builder() + .hexpand(true) + .vexpand(true) + .orientation(Orientation::Vertical) + .sensitive(false) + .build(); + let extra_info_badges_size_group = gtk::SizeGroup::new(SizeGroupMode::Both); + let extra_info_badges_size_group0 = gtk::SizeGroup::new(SizeGroupMode::Both); + let extra_info_badges_size_group1 = gtk::SizeGroup::new(SizeGroupMode::Both); + let package_size = package_size as f64; + let package_installed_size = package_installed_size as f64; + extra_info_badges_content_box.append(&create_color_badge(&t!("extra_info_maintainer").to_string(), package_maintainer, "background-accent-bg", &extra_info_badges_size_group, &extra_info_badges_size_group0, &extra_info_badges_size_group1)); + extra_info_badges_content_box.append(&create_color_badge(&t!("extra_info_download_size").to_string(), &convert(package_size), "background-accent-bg", &extra_info_badges_size_group, &extra_info_badges_size_group0, &extra_info_badges_size_group1)); + extra_info_badges_content_box.append(&create_color_badge(&t!("extra_info_installed_size").to_string(), &convert(package_installed_size), "background-accent-bg", &extra_info_badges_size_group, &extra_info_badges_size_group0, &extra_info_badges_size_group1)); + extra_info_badges_content_box } fn create_color_badge( label0_text: &str, diff --git a/src/apt_package_row/mod.rs b/src/apt_package_row/mod.rs index 52f730b..1048dbc 100644 --- a/src/apt_package_row/mod.rs +++ b/src/apt_package_row/mod.rs @@ -1,8 +1,8 @@ mod imp; +use crate::apt_update_page::AptPackageSocket; use glib::Object; use gtk::glib; -use crate::apt_update_page::AptPackageSocket; glib::wrapper! { pub struct AptPackageRow(ObjectSubclass) @@ -29,7 +29,7 @@ impl AptPackageRow { impl Default for AptPackageRow { fn default() -> Self { - Self::new(AptPackageSocket{ + Self::new(AptPackageSocket { name: "name".to_string(), arch: "arch".to_string(), installed_version: "0.0".to_string(), @@ -38,7 +38,7 @@ impl Default for AptPackageRow { source_uri: "??".to_string(), maintainer: "??".to_string(), size: 0, - installed_size: 0 + installed_size: 0, }) } -} \ No newline at end of file +} diff --git a/src/apt_update/main.rs b/src/apt_update/main.rs index f590d9f..c493cc1 100644 --- a/src/apt_update/main.rs +++ b/src/apt_update/main.rs @@ -1,10 +1,10 @@ +use pika_unixsocket_tools::*; use rust_apt::new_cache; -use tokio::net::{UnixStream}; -use tokio::io::{AsyncReadExt, AsyncWriteExt}; use rust_apt::progress::{AcquireProgress, DynAcquireProgress}; use rust_apt::raw::{AcqTextStatus, ItemDesc, PkgAcquire}; +use tokio::io::{AsyncReadExt, AsyncWriteExt}; +use tokio::net::UnixStream; use tokio::runtime::Runtime; -use pika_unixsocket_tools::*; pub struct AptUpdateProgressSocket<'a> { pulse_interval: usize, @@ -22,7 +22,7 @@ impl<'a> AptUpdateProgressSocket<'a> { max: 0, progress: 0.0, percent_socket_path: percent_socket_path, - status_socket_path: status_socket_path + status_socket_path: status_socket_path, }; progress } @@ -40,7 +40,9 @@ impl<'a> DynAcquireProgress for AptUpdateProgressSocket<'a> { /// The higher the number, the less frequent pulse updates will be. /// /// Pulse Interval set to 0 assumes the apt defaults. - fn pulse_interval(&self) -> usize { self.pulse_interval } + fn pulse_interval(&self) -> usize { + self.pulse_interval + } /// Called when an item is confirmed to be up-to-date. /// @@ -48,7 +50,9 @@ impl<'a> DynAcquireProgress for AptUpdateProgressSocket<'a> { fn hit(&mut self, item: &ItemDesc) { let message = format!("Up-to-date: {} {}", item.description(), item.short_desc()); println!("{}", message); - Runtime::new().unwrap().block_on(send_progress_status(message, self.status_socket_path)); + Runtime::new() + .unwrap() + .block_on(send_progress_status(message, self.status_socket_path)); } /// Called when an Item has started to download @@ -57,7 +61,9 @@ impl<'a> DynAcquireProgress for AptUpdateProgressSocket<'a> { fn fetch(&mut self, item: &ItemDesc) { let message = format!("Fetching: {} {}", item.description(), item.short_desc()); println!("{}", message); - Runtime::new().unwrap().block_on(send_progress_status(message, self.status_socket_path)); + Runtime::new() + .unwrap() + .block_on(send_progress_status(message, self.status_socket_path)); } /// Called when an item is successfully and completely fetched. @@ -66,7 +72,9 @@ impl<'a> DynAcquireProgress for AptUpdateProgressSocket<'a> { fn done(&mut self, item: &ItemDesc) { let message = format!("Downloading: {} {}", item.description(), item.short_desc()); println!("{}", message); - Runtime::new().unwrap().block_on(send_progress_status(message, self.status_socket_path)); + Runtime::new() + .unwrap() + .block_on(send_progress_status(message, self.status_socket_path)); } /// Called when progress has started. @@ -87,9 +95,15 @@ impl<'a> DynAcquireProgress for AptUpdateProgressSocket<'a> { /// /// Print out the ErrorText for the Item. fn fail(&mut self, item: &ItemDesc) { - let message = format!("Download Failed!: {} {}", item.description(), item.short_desc()); + let message = format!( + "Download Failed!: {} {}", + item.description(), + item.short_desc() + ); eprintln!("{}", message); - Runtime::new().unwrap().block_on(send_progress_status(message, self.status_socket_path)); + Runtime::new() + .unwrap() + .block_on(send_progress_status(message, self.status_socket_path)); } /// Called periodically to provide the overall progress information @@ -98,8 +112,12 @@ impl<'a> DynAcquireProgress for AptUpdateProgressSocket<'a> { /// Each line has an overall percent meter and a per active item status /// meter along with an overall bandwidth and ETA indicator. fn pulse(&mut self, status: &AcqTextStatus, owner: &PkgAcquire) { - let progress_percent: f32 = (status.current_bytes() as f32 * 100.0) / status.total_bytes() as f32; - Runtime::new().unwrap().block_on(send_progress_percent(progress_percent, self.percent_socket_path)); + let progress_percent: f32 = + (status.current_bytes() as f32 * 100.0) / status.total_bytes() as f32; + Runtime::new().unwrap().block_on(send_progress_percent( + progress_percent, + self.percent_socket_path, + )); } } @@ -107,14 +125,25 @@ fn main() { let update_cache = new_cache!().unwrap(); let percent_socket_path = "/tmp/pika_apt_update_percent.sock"; let status_socket_path = "/tmp/pika_apt_update_status.sock"; - match update_cache.update(&mut AcquireProgress::new(AptUpdateProgressSocket::new(percent_socket_path, status_socket_path))) { + match update_cache.update(&mut AcquireProgress::new(AptUpdateProgressSocket::new( + percent_socket_path, + status_socket_path, + ))) { Ok(_) => { - Runtime::new().unwrap().block_on(send_successful_to_socket(percent_socket_path)); - Runtime::new().unwrap().block_on(send_successful_to_socket(status_socket_path)); + Runtime::new() + .unwrap() + .block_on(send_successful_to_socket(percent_socket_path)); + Runtime::new() + .unwrap() + .block_on(send_successful_to_socket(status_socket_path)); } Err(e) => { - Runtime::new().unwrap().block_on(send_failed_to_socket(percent_socket_path)); - Runtime::new().unwrap().block_on(send_failed_to_socket(status_socket_path)); + Runtime::new() + .unwrap() + .block_on(send_failed_to_socket(percent_socket_path)); + Runtime::new() + .unwrap() + .block_on(send_failed_to_socket(status_socket_path)); panic!("{}", e.to_string()) } }; @@ -122,17 +151,27 @@ fn main() { async fn send_progress_percent(progress_f32: f32, socket_path: &str) { // Connect to the Unix socket - let mut stream = UnixStream::connect(socket_path).await.expect("Could not connect to server"); + let mut stream = UnixStream::connect(socket_path) + .await + .expect("Could not connect to server"); let message = progress_f32.to_string(); // Send the message to the server - stream.write_all(message.as_bytes()).await.expect("Failed to write to stream"); + stream + .write_all(message.as_bytes()) + .await + .expect("Failed to write to stream"); } async fn send_progress_status(message: String, socket_path: &str) { // Connect to the Unix socket - let mut stream = UnixStream::connect(socket_path).await.expect("Could not connect to server"); + let mut stream = UnixStream::connect(socket_path) + .await + .expect("Could not connect to server"); // Send the message to the server - stream.write_all(message.as_bytes()).await.expect("Failed to write to stream"); -} \ No newline at end of file + stream + .write_all(message.as_bytes()) + .await + .expect("Failed to write to stream"); +} diff --git a/src/apt_update_page/mod.rs b/src/apt_update_page/mod.rs index ae5ac32..9181898 100644 --- a/src/apt_update_page/mod.rs +++ b/src/apt_update_page/mod.rs @@ -1,19 +1,22 @@ -use std::{fs, thread}; -use std::path::Path; -use rust_apt::*; +use crate::apt_package_row::AptPackageRow; +use adw::prelude::*; +use gtk::glib::*; +use gtk::*; +use pika_unixsocket_tools::*; use rust_apt::cache::*; use rust_apt::new_cache; use rust_apt::records::RecordField; +use rust_apt::*; +use std::borrow::BorrowMut; +use std::path::Path; use std::process::Command; -use gtk::glib::*; -use adw::prelude::*; -use gtk::*; -use tokio::net::{UnixListener, UnixStream}; +use std::sync::atomic::AtomicBool; +use std::sync::Arc; +use std::{fs, thread}; use tokio::io::AsyncReadExt; +use tokio::net::{UnixListener, UnixStream}; use tokio::runtime::Runtime; use tokio::task; -use pika_unixsocket_tools::*; -use crate::apt_package_row::AptPackageRow; pub struct AptPackageSocket { pub name: String, @@ -24,7 +27,7 @@ pub struct AptPackageSocket { pub source_uri: String, pub maintainer: String, pub size: u64, - pub installed_size: u64 + pub installed_size: u64, } pub fn apt_update_page(window: adw::ApplicationWindow) -> gtk::Box { @@ -36,11 +39,15 @@ pub fn apt_update_page(window: adw::ApplicationWindow) -> gtk::Box { let get_upgradable_sender = get_upgradable_sender.clone(); thread::spawn(move || { - Runtime::new().unwrap().block_on(update_percent_socket_server(update_percent_sender)); + Runtime::new() + .unwrap() + .block_on(update_percent_socket_server(update_percent_sender)); }); thread::spawn(move || { - Runtime::new().unwrap().block_on(update_status_socket_server(update_status_sender)); + Runtime::new() + .unwrap() + .block_on(update_status_socket_server(update_status_sender)); }); Command::new("pkexec") @@ -68,6 +75,7 @@ pub fn apt_update_page(window: adw::ApplicationWindow) -> gtk::Box { .margin_start(15) .margin_end(15) .margin_start(15) + .sensitive(false) .build(); packages_boxedlist.add_css_class("boxed-list"); let rows_size_group = gtk::SizeGroup::new(SizeGroupMode::Both); @@ -113,17 +121,21 @@ pub fn apt_update_page(window: adw::ApplicationWindow) -> gtk::Box { .width_request(500) .build(); + let mut updates_parsed = Arc::new(AtomicBool::new(false)); + + let update_parsed_clone0 = Arc::clone(&updates_parsed); + let update_percent_server_context = MainContext::default(); // The main loop executes the asynchronous block - update_percent_server_context.spawn_local(clone!(@weak apt_update_dialog_progress_bar, @weak apt_update_dialog, @strong get_upgradable_sender => async move { + update_percent_server_context.spawn_local(clone!(@weak apt_update_dialog_progress_bar, @weak apt_update_dialog, @strong get_upgradable_sender, @strong update_parsed_clone0 => async move { while let Ok(state) = update_percent_receiver.recv().await { match state.as_ref() { "FN_OVERRIDE_SUCCESSFUL" => { let get_upgradable_sender = get_upgradable_sender.clone(); - thread::spawn( move || { + let update_parsed_clone = Arc::clone(&update_parsed_clone0); + thread::spawn(move || { // Create upgradable list cache let upgradable_cache = new_cache!().unwrap(); - // Create pack sort from upgradable_cache let upgradable_sort = PackageSort::default().upgradable().names(); @@ -148,6 +160,7 @@ pub fn apt_update_page(window: adw::ApplicationWindow) -> gtk::Box { }; get_upgradable_sender.send_blocking(package_struct).unwrap() } + update_parsed_clone.store(true, std::sync::atomic::Ordering::Relaxed) }); apt_update_dialog.close(); } @@ -160,7 +173,8 @@ pub fn apt_update_page(window: adw::ApplicationWindow) -> gtk::Box { let update_status_server_context = MainContext::default(); // The main loop executes the asynchronous block - update_status_server_context.spawn_local(clone!(@weak apt_update_dialog, @weak apt_update_dialog_spinner => async move { + update_status_server_context.spawn_local( + clone!(@weak apt_update_dialog, @weak apt_update_dialog_spinner => async move { while let Ok(state) = update_status_receiver.recv().await { match state.as_ref() { "FN_OVERRIDE_SUCCESSFUL" => {} @@ -171,11 +185,14 @@ pub fn apt_update_page(window: adw::ApplicationWindow) -> gtk::Box { _ => apt_update_dialog.set_body(&state) } } - })); + }), + ); + let update_parsed_clone1 = Arc::clone(&updates_parsed); let get_upgradable_server_context = MainContext::default(); // The main loop executes the asynchronous block - get_upgradable_server_context.spawn_local(clone!(@weak packages_boxedlist => async move { + get_upgradable_server_context.spawn_local( + clone!(@weak packages_boxedlist, @strong update_parsed_clone1 => async move { while let Ok(state) = get_upgradable_receiver.recv().await { packages_boxedlist.append(&AptPackageRow::new(AptPackageSocket { name: state.name, @@ -188,9 +205,12 @@ pub fn apt_update_page(window: adw::ApplicationWindow) -> gtk::Box { size: state.size, installed_size: state.installed_size })); + if update_parsed_clone1.load(std::sync::atomic::Ordering::Relaxed) { + packages_boxedlist.set_sensitive(true) + } } - })); - + }), + ); main_box.append(&searchbar); main_box.append(&packages_viewport); @@ -199,7 +219,6 @@ pub fn apt_update_page(window: adw::ApplicationWindow) -> gtk::Box { main_box } - async fn update_percent_socket_server(buffer_sender: async_channel::Sender) { // Path to the Unix socket file let socket_path = "/tmp/pika_apt_update_percent.sock"; @@ -287,4 +306,4 @@ async fn get_upgradable_socket_server(buffer_sender: async_channel::Sender v.into_string().unwrap().chars() + Some(v) => v + .into_string() + .unwrap() + .chars() .take_while(|&ch| ch != '.') .collect::(), None => panic!("$LANG is not set"), }; rust_i18n::set_locale(¤t_locale); - let application = adw::Application::new( - Some(APP_ID), - Default::default(), - ); + let application = adw::Application::new(Some(APP_ID), Default::default()); application.connect_startup(|app| { // The CSS "magic" happens here. let provider = CssProvider::new(); @@ -52,4 +51,4 @@ fn main() { // std::process::exit(1) //} application.run(); -} \ No newline at end of file +} diff --git a/src/pika_unixsocket_tools/lib.rs b/src/pika_unixsocket_tools/lib.rs index 32b438a..d8da124 100644 --- a/src/pika_unixsocket_tools/lib.rs +++ b/src/pika_unixsocket_tools/lib.rs @@ -1,24 +1,34 @@ -use tokio::net::{UnixStream}; use tokio::io::{AsyncReadExt, AsyncWriteExt}; +use tokio::net::UnixStream; pub async fn send_successful_to_socket(socket_path: &str) { // Connect to the Unix socket - let mut stream = UnixStream::connect(socket_path).await.expect("Could not connect to server"); + let mut stream = UnixStream::connect(socket_path) + .await + .expect("Could not connect to server"); let message = "FN_OVERRIDE_SUCCESSFUL"; // Send the message to the server - stream.write_all(message.as_bytes()).await.expect("Failed to write to stream"); + stream + .write_all(message.as_bytes()) + .await + .expect("Failed to write to stream"); } pub async fn send_failed_to_socket(socket_path: &str) { // Connect to the Unix socket - let mut stream = UnixStream::connect(socket_path).await.expect("Could not connect to server"); + let mut stream = UnixStream::connect(socket_path) + .await + .expect("Could not connect to server"); let message = "FN_OVERRIDE_FAILED"; // Send the message to the server - stream.write_all(message.as_bytes()).await.expect("Failed to write to stream"); + stream + .write_all(message.as_bytes()) + .await + .expect("Failed to write to stream"); } // Function to handle a single client connection @@ -30,11 +40,13 @@ pub async fn handle_client(mut stream: UnixStream, buffer_sender: async_channel: match stream.read(&mut buffer).await { Ok(size) => { // Print the received message - buffer_sender.send_blocking(String::from_utf8_lossy(&buffer[..size]).to_string()).expect("Buffer channel closed") + buffer_sender + .send_blocking(String::from_utf8_lossy(&buffer[..size]).to_string()) + .expect("Buffer channel closed") } Err(e) => { // Print error message if reading fails eprintln!("Failed to read from stream: {}", e); } } -} \ No newline at end of file +}