diff --git a/Cargo.lock b/Cargo.lock index b9c2f0d..d771ddf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -292,6 +292,9 @@ name = "bitflags" version = "2.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da" +dependencies = [ + "serde_core", +] [[package]] name = "block" @@ -1380,6 +1383,8 @@ name = "itop" version = "0.1.0" dependencies = [ "iced", + "ron", + "serde", "smol", "sysinfo", ] @@ -2482,6 +2487,20 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832" +[[package]] +name = "ron" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81116b9531d61eabc41aeb228e4b6b2435bcca3233b98cf3b3077d4e6e9debb3" +dependencies = [ + "bitflags 2.13.1", + "once_cell", + "serde", + "serde_derive", + "typeid", + "unicode-ident", +] + [[package]] name = "roxmltree" version = "0.20.0" @@ -3091,6 +3110,12 @@ dependencies = [ "core_maths", ] +[[package]] +name = "typeid" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" + [[package]] name = "uds_windows" version = "1.2.1" diff --git a/Cargo.toml b/Cargo.toml index 5a74d3e..3fbbfc9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,8 @@ version = "0.1.0" edition = "2024" [dependencies] +ron = "0.12.2" +serde = "1.0.229" smol = "2.0.2" sysinfo = "0.39.6" diff --git a/src/app/info_stream.rs b/src/app/info_stream.rs index e7d7632..ed21a87 100644 --- a/src/app/info_stream.rs +++ b/src/app/info_stream.rs @@ -1,28 +1,63 @@ +use std::env; + use iced::{ + Task, futures::{self, SinkExt}, stream, }; -use smol::Timer; +use ron::de; +use smol::{Timer, unblock}; -use crate::sysinfo_snapshot::SysinfoSnapshot; +use crate::{app, sysinfo_snapshot::SysinfoSnapshot}; -pub fn create() -> impl futures::Stream { - stream::channel( - 1, - async |mut sender: futures::channel::mpsc::Sender| { - let mut sys = sysinfo::System::new(); - let refreshes = sysinfo::RefreshKind::nothing() - .with_memory(sysinfo::MemoryRefreshKind::everything()) - .with_cpu(sysinfo::CpuRefreshKind::nothing().with_cpu_usage()); +pub fn create() -> Task { + if env::args() + .nth(1) + .is_some_and(|command| command == "client") + { + Task::run( + stream::channel( + 1, + async |mut sender: futures::channel::mpsc::Sender| { + let mut buf = String::new(); + loop { + buf = unblock(move || { + std::io::stdin().read_line(&mut buf).unwrap(); + buf + }) + .await; - sys.refresh_specifics(refreshes); - Timer::after(sysinfo::MINIMUM_CPU_UPDATE_INTERVAL).await; + match de::from_str(&buf) { + Ok(info) => sender.send(info).await.unwrap(), + Err(e) => eprintln!("{e}"), + } + buf.clear(); + } + }, + ), + app::Message::Info, + ) + } else { + Task::run( + stream::channel( + 1, + async |mut sender: futures::channel::mpsc::Sender| { + let mut sys = sysinfo::System::new(); + let refreshes = sysinfo::RefreshKind::nothing() + .with_memory(sysinfo::MemoryRefreshKind::everything()) + .with_cpu(sysinfo::CpuRefreshKind::nothing().with_cpu_usage()); - loop { - sys.refresh_specifics(refreshes); - sender.send(SysinfoSnapshot::from(&sys)).await.unwrap(); - Timer::after(sysinfo::MINIMUM_CPU_UPDATE_INTERVAL).await; - } - }, - ) + sys.refresh_specifics(refreshes); + Timer::after(sysinfo::MINIMUM_CPU_UPDATE_INTERVAL).await; + + loop { + sys.refresh_specifics(refreshes); + sender.send(SysinfoSnapshot::from(&sys)).await.unwrap(); + Timer::after(sysinfo::MINIMUM_CPU_UPDATE_INTERVAL).await; + } + }, + ), + app::Message::Info, + ) + } } diff --git a/src/app/mod.rs b/src/app/mod.rs index 427e90e..0f038bd 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -1,6 +1,6 @@ use std::time::Duration; -use iced::{Color, Element, Length, Renderer, Task, Theme, application, theme, widget}; +use iced::{Color, Element, Error, Length, Renderer, Task, Theme, application, theme, widget}; use crate::{app::graph::Graph, sysinfo_snapshot::SysinfoSnapshot}; @@ -23,10 +23,7 @@ struct State { impl State { fn new() -> (Self, Task) { - ( - Self::default(), - Task::run(info_stream::create(), Message::Info), - ) + (Self::default(), info_stream::create()) } fn update(&mut self, message: Message) -> Task { match message { @@ -95,7 +92,7 @@ impl State { } } -pub fn run() -> Result<(), impl std::error::Error> { +pub fn run() -> Result<(), Error> { application(State::new, State::update, State::view) .title(State::title) .theme(theme::Theme::custom( diff --git a/src/main.rs b/src/main.rs index fa3e73b..c6dcb49 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,15 @@ +use std::env; + mod app; +mod server; mod sysinfo_snapshot; -fn main() -> Result<(), impl std::error::Error> { - app::run() +fn main() { + match env::args().nth(1).as_deref() { + Some("server") => server::run().unwrap(), + + None | Some("client") => app::run().unwrap(), + + Some(s) => panic!("invalid argument: {s}"), + } } diff --git a/src/server/mod.rs b/src/server/mod.rs new file mode 100644 index 0000000..445f393 --- /dev/null +++ b/src/server/mod.rs @@ -0,0 +1,23 @@ +use std::{io::Write, thread}; + +use ron::{Error, ser}; + +use crate::sysinfo_snapshot::SysinfoSnapshot; + +pub fn run() -> Result<(), Error> { + let mut sys = sysinfo::System::new(); + let refreshes = sysinfo::RefreshKind::nothing() + .with_memory(sysinfo::MemoryRefreshKind::everything()) + .with_cpu(sysinfo::CpuRefreshKind::nothing().with_cpu_usage()); + + sys.refresh_specifics(refreshes); + thread::sleep(sysinfo::MINIMUM_CPU_UPDATE_INTERVAL); + + let mut stdout = std::io::stdout(); + + loop { + sys.refresh_specifics(refreshes); + stdout.write_all((ser::to_string(&SysinfoSnapshot::from(&sys))? + "\n").as_bytes())?; + thread::sleep(sysinfo::MINIMUM_CPU_UPDATE_INTERVAL); + } +} diff --git a/src/sysinfo_snapshot.rs b/src/sysinfo_snapshot.rs index c4bee85..6189cdb 100644 --- a/src/sysinfo_snapshot.rs +++ b/src/sysinfo_snapshot.rs @@ -1,6 +1,6 @@ use std::time::Duration; -#[derive(Clone, Debug)] +#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)] pub struct SysinfoSnapshot { uptime: u64,