Reduce duplication between the tiles
This commit is contained in:
parent
bd09432ba9
commit
187aa4e695
12
Cargo.lock
generated
12
Cargo.lock
generated
|
@ -6,6 +6,17 @@ version = "0.4.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b585a98a234c46fc563103e9278c9391fde1f4e6850334da895d27edb9580f62"
|
checksum = "b585a98a234c46fc563103e9278c9391fde1f4e6850334da895d27edb9580f62"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-trait"
|
||||||
|
version = "0.1.32"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0eb7f9ad01405feb3c1dac82463038945cf88eea4569acaf3ad662233496dd96"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "autocfg"
|
name = "autocfg"
|
||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
|
@ -496,6 +507,7 @@ checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84"
|
||||||
name = "rustybar"
|
name = "rustybar"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"async-trait",
|
||||||
"chrono",
|
"chrono",
|
||||||
"dbus",
|
"dbus",
|
||||||
"dbus-tokio",
|
"dbus-tokio",
|
||||||
|
|
|
@ -6,6 +6,7 @@ edition = "2018"
|
||||||
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
async-trait = "0.1"
|
||||||
chrono = "0.4"
|
chrono = "0.4"
|
||||||
dbus = "0.8"
|
dbus = "0.8"
|
||||||
dbus-tokio = "0.5"
|
dbus-tokio = "0.5"
|
||||||
|
|
35
src/main.rs
35
src/main.rs
|
@ -3,7 +3,6 @@ pub mod tile;
|
||||||
pub mod tiles;
|
pub mod tiles;
|
||||||
|
|
||||||
use dbus_tokio::connection::new_session_sync;
|
use dbus_tokio::connection::new_session_sync;
|
||||||
use tile::Tile;
|
|
||||||
use tokio::sync::mpsc::channel;
|
use tokio::sync::mpsc::channel;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
@ -20,31 +19,21 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
|
||||||
let (sender, receiver) = channel(1024);
|
let (sender, receiver) = channel(1024);
|
||||||
|
|
||||||
let tiles: Vec<Box<dyn Tile>> = vec![
|
let mut index = 0usize;
|
||||||
Box::new(tiles::Load::new(
|
let mut wrap = |module| {
|
||||||
0,
|
let tile = tile::Tile::new(index, sender.clone(), Uuid::new_v4().to_string().into(), module);
|
||||||
sender.clone(),
|
index += 1;
|
||||||
Uuid::new_v4().to_string().into(),
|
tile
|
||||||
)),
|
};
|
||||||
Box::new(tiles::Memory::new(
|
let tiles = vec![
|
||||||
1,
|
wrap(Box::new(tiles::Load::new())),
|
||||||
sender.clone(),
|
wrap(Box::new(tiles::Memory::new())),
|
||||||
Uuid::new_v4().to_string().into(),
|
wrap(Box::new(tiles::Hostname::new())),
|
||||||
)),
|
wrap(Box::new(tiles::Time::new())),
|
||||||
Box::new(tiles::Hostname::new(
|
|
||||||
2,
|
|
||||||
sender.clone(),
|
|
||||||
Uuid::new_v4().to_string().into(),
|
|
||||||
)),
|
|
||||||
Box::new(tiles::Time::new(
|
|
||||||
3,
|
|
||||||
sender,
|
|
||||||
Uuid::new_v4().to_string().into(),
|
|
||||||
)),
|
|
||||||
];
|
];
|
||||||
|
|
||||||
let num_tiles = tiles.len();
|
let num_tiles = tiles.len();
|
||||||
for tile in tiles {
|
for tile in tiles.into_iter() {
|
||||||
tile.spawn();
|
tile.spawn();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
50
src/tile.rs
50
src/tile.rs
|
@ -1,6 +1,9 @@
|
||||||
|
use async_trait::async_trait;
|
||||||
use serde::{ser::Serializer, Serialize};
|
use serde::{ser::Serializer, Serialize};
|
||||||
use smart_default::SmartDefault;
|
use smart_default::SmartDefault;
|
||||||
|
use std::fmt::Debug;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
use tokio::sync::mpsc::{error::SendError, Sender};
|
||||||
use tokio::task::JoinHandle;
|
use tokio::task::JoinHandle;
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Serialize)]
|
#[derive(Copy, Clone, Debug, Serialize)]
|
||||||
|
@ -80,6 +83,49 @@ pub struct TileData {
|
||||||
pub block: Block,
|
pub block: Block,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Tile: Send + std::fmt::Debug {
|
#[async_trait]
|
||||||
fn spawn(self: Box<Self>) -> JoinHandle<Result<(), Box<dyn std::error::Error + Send + Sync>>>;
|
pub trait TileModule: Send + std::fmt::Debug {
|
||||||
|
async fn run(&mut self, sender: &mut BlockSender) -> Result<(), Box<dyn std::error::Error + Send + Sync>>;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct BlockSender {
|
||||||
|
sender_id: usize,
|
||||||
|
sender: Sender<TileData>,
|
||||||
|
instance: Arc<str>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BlockSender {
|
||||||
|
pub async fn send(&mut self, mut block: Block) -> Result<(), SendError<TileData>> {
|
||||||
|
block.instance = self.instance.clone();
|
||||||
|
let data = TileData {
|
||||||
|
block,
|
||||||
|
sender_id: self.sender_id,
|
||||||
|
};
|
||||||
|
self.sender.send(data).await
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Tile {
|
||||||
|
sender: BlockSender,
|
||||||
|
module: Box<dyn TileModule>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Tile {
|
||||||
|
pub fn new(sender_id: usize, sender: Sender<TileData>, instance: Arc<str>, module: Box<dyn TileModule>) -> Self {
|
||||||
|
Tile {
|
||||||
|
sender: BlockSender {
|
||||||
|
sender_id,
|
||||||
|
sender,
|
||||||
|
instance,
|
||||||
|
},
|
||||||
|
module,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn spawn(mut self) -> JoinHandle<Result<(), Box<dyn std::error::Error + Send + Sync>>> {
|
||||||
|
tokio::spawn(async move {
|
||||||
|
self.module.run(&mut self.sender).await
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,31 +1,20 @@
|
||||||
use crate::tile::{Block, Tile, TileData};
|
use crate::tile::{Block, BlockSender, TileModule};
|
||||||
use std::sync::Arc;
|
use async_trait::async_trait;
|
||||||
use tokio::fs::File;
|
use tokio::fs::File;
|
||||||
use tokio::prelude::*;
|
use tokio::prelude::*;
|
||||||
use tokio::sync::mpsc::{error::SendError, Sender};
|
|
||||||
use tokio::task::JoinHandle;
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Default)]
|
||||||
pub struct Hostname {
|
pub struct Hostname;
|
||||||
sender_id: usize,
|
|
||||||
sender: Sender<TileData>,
|
|
||||||
instance: Arc<str>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Hostname {
|
impl Hostname {
|
||||||
pub fn new(sender_id: usize, sender: Sender<TileData>, instance: Arc<str>) -> Hostname {
|
pub fn new() -> Hostname {
|
||||||
Hostname {
|
Hostname
|
||||||
sender_id,
|
|
||||||
sender,
|
|
||||||
instance,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async fn send(&mut self, data: TileData) -> Result<(), SendError<TileData>> {
|
#[async_trait]
|
||||||
self.sender.send(data).await
|
impl TileModule for Hostname {
|
||||||
}
|
async fn run(&mut self, sender: &mut BlockSender) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||||
|
|
||||||
async fn run(&mut self) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
|
||||||
let mut raw = String::new();
|
let mut raw = String::new();
|
||||||
File::open("/proc/sys/kernel/hostname")
|
File::open("/proc/sys/kernel/hostname")
|
||||||
.await?
|
.await?
|
||||||
|
@ -33,24 +22,11 @@ impl Hostname {
|
||||||
.await?;
|
.await?;
|
||||||
let block = Block {
|
let block = Block {
|
||||||
full_text: raw.trim_end_matches('\n').into(),
|
full_text: raw.trim_end_matches('\n').into(),
|
||||||
instance: self.instance.clone(),
|
|
||||||
name: "hostname".into(),
|
name: "hostname".into(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
let data = TileData {
|
sender.send(block).await?;
|
||||||
block,
|
|
||||||
sender_id: self.sender_id,
|
|
||||||
};
|
|
||||||
self.send(data).await?;
|
|
||||||
// What's the hostname gonna do? Change?
|
// What's the hostname gonna do? Change?
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Tile for Hostname {
|
|
||||||
fn spawn(mut self: Box<Self>) -> JoinHandle<Result<(), Box<dyn std::error::Error + Send + Sync>>> {
|
|
||||||
tokio::spawn(async move {
|
|
||||||
self.run().await
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,33 +1,22 @@
|
||||||
use crate::tile::{Block, Tile, TileData};
|
use crate::tile::{Block, BlockSender, TileModule};
|
||||||
use std::sync::Arc;
|
use async_trait::async_trait;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use tokio::fs::File;
|
use tokio::fs::File;
|
||||||
use tokio::prelude::*;
|
use tokio::prelude::*;
|
||||||
use tokio::sync::mpsc::{error::SendError, Sender};
|
|
||||||
use tokio::task::JoinHandle;
|
|
||||||
use tokio::time::interval;
|
use tokio::time::interval;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Default)]
|
||||||
pub struct Load {
|
pub struct Load;
|
||||||
sender_id: usize,
|
|
||||||
sender: Sender<TileData>,
|
|
||||||
instance: Arc<str>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Load {
|
impl Load {
|
||||||
pub fn new(sender_id: usize, sender: Sender<TileData>, instance: Arc<str>) -> Load {
|
pub fn new() -> Self {
|
||||||
Load {
|
Load
|
||||||
sender_id,
|
|
||||||
sender,
|
|
||||||
instance,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async fn send(&mut self, data: TileData) -> Result<(), SendError<TileData>> {
|
#[async_trait]
|
||||||
self.sender.send(data).await
|
impl TileModule for Load {
|
||||||
}
|
async fn run(&mut self, sender: &mut BlockSender) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||||
|
|
||||||
async fn run(&mut self) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
|
||||||
let mut timer = interval(Duration::from_secs(5));
|
let mut timer = interval(Duration::from_secs(5));
|
||||||
loop {
|
loop {
|
||||||
timer.tick().await;
|
timer.tick().await;
|
||||||
|
@ -39,23 +28,10 @@ impl Load {
|
||||||
let (load, _rest) = raw.split_at(raw.find(' ').unwrap_or(0));
|
let (load, _rest) = raw.split_at(raw.find(' ').unwrap_or(0));
|
||||||
let block = Block {
|
let block = Block {
|
||||||
full_text: load.into(),
|
full_text: load.into(),
|
||||||
instance: self.instance.clone(),
|
|
||||||
name: "load".into(),
|
name: "load".into(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
let data = TileData {
|
sender.send(block).await?;
|
||||||
block,
|
|
||||||
sender_id: self.sender_id,
|
|
||||||
};
|
|
||||||
self.send(data).await?;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Tile for Load {
|
|
||||||
fn spawn(mut self: Box<Self>) -> JoinHandle<Result<(), Box<dyn std::error::Error + Send + Sync>>> {
|
|
||||||
tokio::spawn(async move {
|
|
||||||
self.run().await
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,32 +1,18 @@
|
||||||
use crate::tile::{Block, Tile, TileData};
|
use crate::tile::{Block, BlockSender, TileModule};
|
||||||
|
use async_trait::async_trait;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::str;
|
use std::str;
|
||||||
use std::sync::Arc;
|
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use tokio::fs::File;
|
use tokio::fs::File;
|
||||||
use tokio::prelude::*;
|
use tokio::prelude::*;
|
||||||
use tokio::sync::mpsc::{error::SendError, Sender};
|
|
||||||
use tokio::task::JoinHandle;
|
|
||||||
use tokio::time::interval;
|
use tokio::time::interval;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Default)]
|
||||||
pub struct Memory {
|
pub struct Memory;
|
||||||
sender_id: usize,
|
|
||||||
sender: Sender<TileData>,
|
|
||||||
instance: Arc<str>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Memory {
|
impl Memory {
|
||||||
pub fn new(sender_id: usize, sender: Sender<TileData>, instance: Arc<str>) -> Memory {
|
pub fn new() -> Memory {
|
||||||
Memory {
|
Memory
|
||||||
sender_id,
|
|
||||||
sender,
|
|
||||||
instance,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn send(&mut self, data: TileData) -> Result<(), SendError<TileData>> {
|
|
||||||
self.sender.send(data).await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn prettify_kib(kib: u64) -> Box<str> {
|
fn prettify_kib(kib: u64) -> Box<str> {
|
||||||
|
@ -64,8 +50,11 @@ impl Memory {
|
||||||
.ok_or_else(|| io::Error::from(io::ErrorKind::InvalidData))?
|
.ok_or_else(|| io::Error::from(io::ErrorKind::InvalidData))?
|
||||||
.parse()?)
|
.parse()?)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async fn run(&mut self) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
#[async_trait]
|
||||||
|
impl TileModule for Memory {
|
||||||
|
async fn run(&mut self, sender: &mut BlockSender) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||||
let mut timer = interval(Duration::from_secs(5));
|
let mut timer = interval(Duration::from_secs(5));
|
||||||
let mut raw = [0u8; 256];
|
let mut raw = [0u8; 256];
|
||||||
loop {
|
loop {
|
||||||
|
@ -94,25 +83,10 @@ impl Memory {
|
||||||
let block = Block {
|
let block = Block {
|
||||||
full_text,
|
full_text,
|
||||||
short_text: Some(short_text),
|
short_text: Some(short_text),
|
||||||
instance: self.instance.clone(),
|
|
||||||
name: "memory".into(),
|
name: "memory".into(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
let data = TileData {
|
sender.send(block).await?;
|
||||||
block,
|
|
||||||
sender_id: self.sender_id,
|
|
||||||
};
|
|
||||||
self.send(data).await?;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Tile for Memory {
|
|
||||||
fn spawn(mut self: Box<Self>) -> JoinHandle<Result<(), Box<dyn std::error::Error + Send + Sync>>> {
|
|
||||||
tokio::spawn(async move {
|
|
||||||
let result = self.run().await;
|
|
||||||
eprintln!("Error in Memory: {:?}", result);
|
|
||||||
result
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,55 +1,46 @@
|
||||||
use crate::tile::{Block, Tile, TileData};
|
use crate::tile::{Block, BlockSender, TileModule};
|
||||||
|
use async_trait::async_trait;
|
||||||
use chrono::prelude::*;
|
use chrono::prelude::*;
|
||||||
use chrono::DateTime;
|
use chrono::DateTime;
|
||||||
use std::sync::Arc;
|
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use tokio::sync::mpsc::{error::SendError, Sender};
|
|
||||||
use tokio::task::JoinHandle;
|
|
||||||
use tokio::time::delay_for;
|
use tokio::time::delay_for;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Time {
|
pub struct Time {
|
||||||
sender_id: usize,
|
|
||||||
sender: Sender<TileData>,
|
|
||||||
instance: Arc<str>,
|
|
||||||
format: Box<str>,
|
format: Box<str>,
|
||||||
short_format: Box<str>,
|
short_format: Box<str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Time {
|
impl Time {
|
||||||
pub fn new(sender_id: usize, sender: Sender<TileData>, instance: Arc<str>) -> Time {
|
pub fn new() -> Time {
|
||||||
|
Default::default()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn send_time(&mut self, time: DateTime<Local>) -> Block {
|
||||||
|
Block {
|
||||||
|
full_text: time.format(&self.format).to_string().into(),
|
||||||
|
short_text: Some(time.format(&self.short_format).to_string().into()),
|
||||||
|
name: "time".into(),
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Time {
|
||||||
|
fn default() -> Self {
|
||||||
Time {
|
Time {
|
||||||
sender_id,
|
|
||||||
sender,
|
|
||||||
instance,
|
|
||||||
format: "%Y-%m-%d %H:%M:%S".into(),
|
format: "%Y-%m-%d %H:%M:%S".into(),
|
||||||
short_format: "%H:%M:%S".into(),
|
short_format: "%H:%M:%S".into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async fn send(&mut self, data: TileData) -> Result<(), SendError<TileData>> {
|
#[async_trait]
|
||||||
self.sender.send(data).await
|
impl TileModule for Time {
|
||||||
}
|
async fn run(&mut self, sender: &mut BlockSender) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||||
|
|
||||||
async fn send_time(&mut self, time: DateTime<Local>) -> Result<(), SendError<TileData>> {
|
|
||||||
let block = Block {
|
|
||||||
full_text: time.format(&self.format).to_string().into(),
|
|
||||||
short_text: Some(time.format(&self.short_format).to_string().into()),
|
|
||||||
instance: self.instance.clone(),
|
|
||||||
name: "time".into(),
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
let data = TileData {
|
|
||||||
sender_id: self.sender_id,
|
|
||||||
block,
|
|
||||||
};
|
|
||||||
self.send(data).await
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn run(&mut self) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
|
||||||
let mut time = Local::now();
|
let mut time = Local::now();
|
||||||
loop {
|
loop {
|
||||||
self.send_time(time).await?;
|
sender.send(self.send_time(time)).await?;
|
||||||
time = Local::now();
|
time = Local::now();
|
||||||
let millis_part = time.naive_local().timestamp_subsec_millis() as u64;
|
let millis_part = time.naive_local().timestamp_subsec_millis() as u64;
|
||||||
let delay_ms = 1000u64 - millis_part % 1000; // Don't crash if we hit a leap second
|
let delay_ms = 1000u64 - millis_part % 1000; // Don't crash if we hit a leap second
|
||||||
|
@ -57,11 +48,3 @@ impl Time {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Tile for Time {
|
|
||||||
fn spawn(mut self: Box<Self>) -> JoinHandle<Result<(), Box<dyn std::error::Error + Send + Sync>>> {
|
|
||||||
tokio::spawn(async move {
|
|
||||||
self.run().await
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue