Initial commit, outputs bar that almost works

master
Rasmus Rosengren 3 years ago
commit 2f404f3646
Signed by: rsrp
GPG Key ID: A13BC7BC4F81CF5F
  1. 1
      .gitignore
  2. 283
      Cargo.lock
  3. 11
      Cargo.toml
  4. 124
      src/main.rs
  5. 38
      src/protocol/i3bar_block.rs
  6. 90
      src/protocol/i3bar_event.rs
  7. 6
      src/protocol/mod.rs

1
.gitignore vendored

@ -0,0 +1 @@
/target

283
Cargo.lock generated

@ -0,0 +1,283 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "bumpalo"
version = "3.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c59e7af012c713f529e7a3ee57ce9b31ddd858d4b512923602f74608b009631"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "flume"
version = "0.10.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24c3fd473b3a903a62609e413ed7538f99e10b665ecb502b5e481a95283f8ab4"
dependencies = [
"futures-core",
"futures-sink",
"nanorand",
"pin-project",
"spin",
]
[[package]]
name = "futures-core"
version = "0.3.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af51b1b4a7fdff033703db39de8802c673eb91855f2e0d47dcf3bf2c0ef01f99"
[[package]]
name = "futures-sink"
version = "0.3.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0f30aaa67363d119812743aa5f33c201a7a66329f97d1a887022971feea4b53"
[[package]]
name = "getrandom"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753"
dependencies = [
"cfg-if",
"js-sys",
"libc",
"wasi",
"wasm-bindgen",
]
[[package]]
name = "i3status-simple"
version = "0.1.0"
dependencies = [
"flume",
"serde",
"serde_json",
]
[[package]]
name = "itoa"
version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4"
[[package]]
name = "js-sys"
version = "0.3.53"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e4bf49d50e2961077d9c99f4b7997d770a1114f087c3c2e0069b36c13fc2979d"
dependencies = [
"wasm-bindgen",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.101"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3cb00336871be5ed2c8ed44b60ae9959dc5b9f08539422ed43f09e34ecaeba21"
[[package]]
name = "lock_api"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0382880606dff6d15c9476c416d18690b72742aa7b605bb6dd6ec9030fbf07eb"
dependencies = [
"scopeguard",
]
[[package]]
name = "log"
version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
dependencies = [
"cfg-if",
]
[[package]]
name = "nanorand"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "729eb334247daa1803e0a094d0a5c55711b85571179f5ec6e53eccfdf7008958"
dependencies = [
"getrandom",
]
[[package]]
name = "pin-project"
version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "576bc800220cc65dac09e99e97b08b358cfab6e17078de8dc5fee223bd2d0c08"
dependencies = [
"pin-project-internal",
]
[[package]]
name = "pin-project-internal"
version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e8fe8163d14ce7f0cdac2e040116f22eac817edabff0be91e8aff7e9accf389"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "proc-macro2"
version = "1.0.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612"
dependencies = [
"unicode-xid",
]
[[package]]
name = "quote"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
dependencies = [
"proc-macro2",
]
[[package]]
name = "ryu"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
[[package]]
name = "scopeguard"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "serde"
version = "1.0.129"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d1f72836d2aa753853178eda473a3b9d8e4eefdaf20523b919677e6de489f8f1"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.129"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e57ae87ad533d9a56427558b516d0adac283614e347abf85b0dc0cbbf0a249f3"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.66"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "336b10da19a12ad094b59d870ebde26a45402e5b470add4b5fd03c5048a32127"
dependencies = [
"itoa",
"ryu",
"serde",
]
[[package]]
name = "spin"
version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "511254be0c5bcf062b019a6c89c01a664aa359ded62f78aa72c6fc137c0590e5"
dependencies = [
"lock_api",
]
[[package]]
name = "syn"
version = "1.0.75"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b7f58f7e8eaa0009c5fec437aabf511bd9933e4b2d7407bd05273c01a8906ea7"
dependencies = [
"proc-macro2",
"quote",
"unicode-xid",
]
[[package]]
name = "unicode-xid"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
[[package]]
name = "wasi"
version = "0.10.2+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
[[package]]
name = "wasm-bindgen"
version = "0.2.76"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ce9b1b516211d33767048e5d47fa2a381ed8b76fc48d2ce4aa39877f9f183e0"
dependencies = [
"cfg-if",
"wasm-bindgen-macro",
]
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.76"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cfe8dc78e2326ba5f845f4b5bf548401604fa20b1dd1d365fb73b6c1d6364041"
dependencies = [
"bumpalo",
"lazy_static",
"log",
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.76"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44468aa53335841d9d6b6c023eaab07c0cd4bddbcfdee3e2bb1e8d2cb8069fef"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
]
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.76"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0195807922713af1e67dc66132c7328206ed9766af3858164fb583eedc25fbad"
dependencies = [
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.76"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "acdb075a845574a1fa5f09fd77e43f7747599301ea3417a9fbffdeedfc1f4a29"

@ -0,0 +1,11 @@
[package]
name = "i3status-simple"
version = "0.1.0"
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
flume = "0.10"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"

@ -0,0 +1,124 @@
use std::sync::mpsc;
use std::{collections::HashMap, io::Write};
use protocol::i3bar_event::I3BarEvent;
use crate::protocol::{
i3bar_block::{write_blocks, I3BarBlock},
i3bar_event::read_event,
};
mod protocol;
fn main() {
protocol::init();
let (event_s, event_r) = flume::unbounded();
std::thread::spawn(move || loop {
let event = read_event().unwrap();
event_s.send(event).unwrap();
});
let blocks = vec![
TestBlock { id: 0, n: 0 },
TestBlock { id: 1, n: 1 },
TestBlock { id: 2, n: 2 },
TestBlock { id: 3, n: 3 },
];
let (update_s, update_r) = flume::unbounded();
let block_ids: Vec<_> = blocks.iter().map(|b| b.id()).collect();
for block in blocks {
let event_r = event_r.clone();
let update_s = update_s.clone();
std::thread::spawn(move || {
block.run(event_r, update_s);
});
}
let mut cache = HashMap::new();
loop {
let (id, content) = update_r.recv().unwrap();
cache.insert(id, content);
let rendered_blocks = block_ids
.iter()
.filter_map(|id| cache.get(id).map(|content| content.clone()))
.map(|content| I3BarBlock {
full_text: content,
color: Some(String::from("#ff0000")),
background: Some(String::from("#00ff00")),
border: Some(String::from("#0000ff")),
border_right: Some(16),
border_left: Some(16),
..Default::default()
})
.collect();
write_blocks(rendered_blocks);
}
}
pub trait Block {
fn id(&self) -> usize;
fn name(&self) -> &str;
fn run(self, event_r: flume::Receiver<I3BarEvent>, update_s: flume::Sender<(usize, String)>);
}
pub enum Event {
I3Bar(I3BarEvent),
Poll,
}
struct TestBlock {
id: usize,
n: i32,
}
impl Block for TestBlock {
fn id(&self) -> usize {
self.id
}
fn name(&self) -> &str {
"test"
}
fn run(
mut self,
event_r: flume::Receiver<I3BarEvent>,
update_s: flume::Sender<(usize, String)>,
) {
let (poll_s, poll_r) = flume::unbounded();
std::thread::spawn(move || loop {
std::thread::sleep(std::time::Duration::from_millis(333));
poll_s.send(()).unwrap();
});
loop {
flume::Selector::new()
.recv(&event_r, |msg| msg.map(|msg| Event::I3Bar(msg)))
.recv(&poll_r, |_| Ok(Event::Poll))
.wait()
.unwrap();
self.n += 1;
update_s
.send((self.id(), format!(" hello {} ", self.n)))
.unwrap();
}
}
}
pub fn debug<'s, S1, S2>(loc: S1, content: S2)
where
S1: AsRef<str>,
S2: AsRef<str>,
{
let mut file = std::fs::OpenOptions::new()
.append(true)
.create(true)
.open("/home/rosen/dev/i3status-simple/debug.log")
.unwrap();
file.write_all(format!("[{:?}]: {:?}\n", loc.as_ref(), content.as_ref()).as_bytes())
.unwrap();
}

@ -0,0 +1,38 @@
use serde::Serialize;
#[derive(Clone, Debug, Default, Serialize)]
pub struct I3BarBlock {
pub full_text: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub short_text: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub color: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub background: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub border: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub border_top: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub border_right: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub border_bottom: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub border_left: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub min_width: Option<i32>,
pub name: String,
pub instance: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub urgent: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub separator: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub separator_block_width: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub markup: Option<String>,
}
pub fn write_blocks(blocks: Vec<I3BarBlock>) {
println!("{},", serde_json::to_string(&blocks).unwrap());
}

@ -0,0 +1,90 @@
use serde::{de, Deserialize, Deserializer};
#[derive(Clone, Debug, Deserialize)]
pub struct I3BarEvent {
pub name: String,
pub instance: String,
pub x: i32,
pub y: i32,
#[serde(deserialize_with = "deserialize_mousebutton")]
pub button: I3BarEventButton,
pub relative_x: i32,
pub relative_y: i32,
pub output_x: i32,
pub output_y: i32,
pub width: i32,
pub height: i32,
pub modifiers: Vec<I3BarEventModifier>,
}
pub fn read_event() -> std::io::Result<I3BarEvent> {
let mut line = String::new();
std::io::stdin().read_line(&mut line)?;
let slice = line.trim_start_matches(|c| c != '{');
let slice = slice.trim_end_matches(|c| c != '}');
// If empty line, read another line
if slice == "" {
return read_event();
}
Ok(serde_json::from_str(slice).unwrap())
}
#[derive(Clone, Debug)]
pub enum I3BarEventButton {
LeftMouse,
MiddleMouse,
RightMouse,
ScrollUp,
ScrollDown,
ScrollRight,
ScrollLeft,
}
fn deserialize_mousebutton<'de, D>(deserializer: D) -> Result<I3BarEventButton, D::Error>
where
D: Deserializer<'de>,
{
struct I3BarEventButtonVisitor;
impl<'de> de::Visitor<'de> for I3BarEventButtonVisitor {
type Value = I3BarEventButton;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("u64")
}
fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(match v {
1 => I3BarEventButton::LeftMouse,
2 => I3BarEventButton::MiddleMouse,
3 => I3BarEventButton::RightMouse,
4 => I3BarEventButton::ScrollUp,
5 => I3BarEventButton::ScrollDown,
6 => I3BarEventButton::ScrollRight,
7 => I3BarEventButton::ScrollLeft,
_ => {
return Err(de::Error::invalid_value(
de::Unexpected::Unsigned(v),
&"1-7",
))
}
})
}
}
deserializer.deserialize_any(I3BarEventButtonVisitor)
}
#[derive(Clone, Debug, Deserialize)]
pub enum I3BarEventModifier {
Mod1,
Mod4,
Control,
Shift,
}

@ -0,0 +1,6 @@
pub mod i3bar_block;
pub mod i3bar_event;
pub fn init() {
println!(r#"{{ "version": 1, "click_events": true }}["#)
}
Loading…
Cancel
Save