Add basic support for config files
This commit is contained in:
parent
f08d1bdc7d
commit
7db23d0a70
155
Cargo.lock
generated
155
Cargo.lock
generated
|
@ -1,5 +1,14 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "ansi_term"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
|
||||
dependencies = [
|
||||
"winapi 0.3.8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "arc-swap"
|
||||
version = "0.4.6"
|
||||
|
@ -17,6 +26,17 @@ dependencies = [
|
|||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
"winapi 0.3.8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.0.0"
|
||||
|
@ -52,6 +72,21 @@ dependencies = [
|
|||
"time",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "2.33.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bdfa80d47f954d53a35a64987ca1422f495b8d6483c0fe9f7117b36c2a792129"
|
||||
dependencies = [
|
||||
"ansi_term",
|
||||
"atty",
|
||||
"bitflags",
|
||||
"strsim",
|
||||
"textwrap",
|
||||
"unicode-width",
|
||||
"vec_map",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dbus"
|
||||
version = "0.8.3"
|
||||
|
@ -202,6 +237,15 @@ dependencies = [
|
|||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205"
|
||||
dependencies = [
|
||||
"unicode-segmentation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.13"
|
||||
|
@ -426,6 +470,32 @@ version = "0.2.8"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "237a5ed80e274dbc66f86bd59c1e25edc039660be53194b5fe0a482e0f2612ea"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "98e9e4b82e0ef281812565ea4751049f1bdcdfccda7d3f459f2e138a40c08678"
|
||||
dependencies = [
|
||||
"proc-macro-error-attr",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error-attr"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4f5444ead4e9935abd7f27dc51f7e852a0569ac888096d5ec2499470794e2e53"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn-mid",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-hack"
|
||||
version = "0.5.16"
|
||||
|
@ -514,7 +584,9 @@ dependencies = [
|
|||
"serde",
|
||||
"serde_json",
|
||||
"smart-default",
|
||||
"structopt",
|
||||
"tokio",
|
||||
"toml",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
|
@ -594,6 +666,36 @@ dependencies = [
|
|||
"winapi 0.3.8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
||||
|
||||
[[package]]
|
||||
name = "structopt"
|
||||
version = "0.3.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "863246aaf5ddd0d6928dfeb1a9ca65f505599e4e1b399935ef7e75107516b4ef"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"lazy_static",
|
||||
"structopt-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "structopt-derive"
|
||||
version = "0.4.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d239ca4b13aee7a2142e6795cbd69e457665ff8037aed33b3effdc430d2f927a"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.28"
|
||||
|
@ -605,6 +707,26 @@ dependencies = [
|
|||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn-mid"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7be3539f6c128a931cf19dcee741c1af532c7fd387baa739c03dd2e96479338a"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "textwrap"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
|
||||
dependencies = [
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.1.43"
|
||||
|
@ -650,6 +772,27 @@ dependencies = [
|
|||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.5.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-segmentation"
|
||||
version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "caaa9d531767d1ff2150b9332433f32a24622147e5ebb1f26409d5da67afd479"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.0"
|
||||
|
@ -665,6 +808,18 @@ dependencies = [
|
|||
"rand",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "vec_map"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.9.0+wasi-snapshot-preview1"
|
||||
|
|
|
@ -13,5 +13,12 @@ dbus-tokio = "0.5"
|
|||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
smart-default = "0.6"
|
||||
structopt = "0.3"
|
||||
tokio = { version = "0.2", features = ["full"] }
|
||||
toml = "0.5"
|
||||
uuid = { version = "0.8", features = [ "v4" ] }
|
||||
|
||||
[profile.release]
|
||||
incremental = false
|
||||
codegen-units = 1
|
||||
lto = true
|
||||
|
|
12
config.toml.example
Normal file
12
config.toml.example
Normal file
|
@ -0,0 +1,12 @@
|
|||
[[tile]]
|
||||
type = "load"
|
||||
|
||||
[[tile]]
|
||||
type = "memory"
|
||||
|
||||
[[tile]]
|
||||
type = "hostname"
|
||||
|
||||
[[tile]]
|
||||
type = "time"
|
||||
format = "%Y-%m-%dT%H:%M:%S"
|
92
src/config.rs
Normal file
92
src/config.rs
Normal file
|
@ -0,0 +1,92 @@
|
|||
use crate::tile::TileModule;
|
||||
use crate::tiles;
|
||||
use serde::Deserialize;
|
||||
use smart_default::SmartDefault;
|
||||
use std::env::var;
|
||||
use std::io;
|
||||
use std::path::PathBuf;
|
||||
use structopt::StructOpt;
|
||||
use tokio::fs::File;
|
||||
use tokio::prelude::*;
|
||||
|
||||
#[derive(Deserialize, Clone, Debug, Default)]
|
||||
#[serde(default)]
|
||||
pub struct Config {
|
||||
pub default: DefaultSection,
|
||||
pub tile: Box<[TileConfig]>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Clone, Debug, Default)]
|
||||
pub struct DefaultSection {
|
||||
pub spacing: Option<u32>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Clone, Debug)]
|
||||
#[serde(tag = "type", rename_all = "snake_case")]
|
||||
pub enum TileConfig {
|
||||
Memory,
|
||||
Load,
|
||||
Hostname,
|
||||
Time(TimeConfig),
|
||||
}
|
||||
|
||||
#[derive(SmartDefault, Deserialize, Clone, Debug)]
|
||||
#[serde(default)]
|
||||
pub struct TimeConfig {
|
||||
#[default("%Y-%m-%d %H:%M:%S")]
|
||||
pub format: Box<str>,
|
||||
#[default("%H:%M:%S")]
|
||||
pub short_format: Box<str>,
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
#[structopt(
|
||||
name = "rustybar",
|
||||
about = "Something to exec for your swaybar or i3bar"
|
||||
)]
|
||||
struct Args {
|
||||
/// Configuration file, default is $XDG_CONFIG_HOME/rustybar/config.toml
|
||||
#[structopt(short, long, parse(from_os_str))]
|
||||
pub config: Option<PathBuf>,
|
||||
}
|
||||
|
||||
pub async fn read_config() -> Result<Config, Box<dyn std::error::Error>> {
|
||||
let args = Args::from_args();
|
||||
let config_path = match args.config {
|
||||
Some(config) => config,
|
||||
None => {
|
||||
if let Ok(rustybar_config_env) = var("RUSTYBAR_CONFIG") {
|
||||
rustybar_config_env.into()
|
||||
} else if let Ok(xdg_config_home) = var("XDG_CONFIG_HOME") {
|
||||
[&xdg_config_home, "rustybar", "config.toml"]
|
||||
.iter()
|
||||
.collect()
|
||||
} else if let Ok(home) = var("HOME") {
|
||||
[&home, ".config", "rustybar", "config.toml"]
|
||||
.iter()
|
||||
.collect()
|
||||
} else {
|
||||
return Err(Box::new(io::Error::new(
|
||||
io::ErrorKind::NotFound,
|
||||
"Could not find RUSTYBAR_CONFIG, XDG_CONFIG_HOME, or HOME environment variables"
|
||||
)));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let mut config_contents = vec![];
|
||||
File::open(config_path)
|
||||
.await?
|
||||
.read_to_end(&mut config_contents)
|
||||
.await?;
|
||||
Ok(toml::from_slice(&config_contents)?)
|
||||
}
|
||||
|
||||
pub fn process_tile(tile: &TileConfig) -> Box<dyn TileModule> {
|
||||
match tile {
|
||||
TileConfig::Load => Box::new(tiles::Hostname::new()),
|
||||
TileConfig::Memory => Box::new(tiles::Memory::new()),
|
||||
TileConfig::Hostname => Box::new(tiles::Hostname::new()),
|
||||
TileConfig::Time(c) => Box::new(tiles::Time::from_config(c)),
|
||||
}
|
||||
}
|
20
src/main.rs
20
src/main.rs
|
@ -1,3 +1,4 @@
|
|||
pub mod config;
|
||||
pub mod output;
|
||||
pub mod tile;
|
||||
pub mod tiles;
|
||||
|
@ -8,6 +9,8 @@ use uuid::Uuid;
|
|||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let config = config::read_config().await?;
|
||||
|
||||
// We can't do much until we have a D-Bus connection so just do it synchronously
|
||||
let (resource, _conn) = new_session_sync()?;
|
||||
|
||||
|
@ -20,7 +23,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
let (sender, receiver) = channel(1024);
|
||||
|
||||
let mut index = 0usize;
|
||||
let mut wrap = |module| {
|
||||
let wrap = |module| {
|
||||
let tile = tile::Tile::new(
|
||||
index,
|
||||
sender.clone(),
|
||||
|
@ -30,17 +33,18 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
index += 1;
|
||||
tile
|
||||
};
|
||||
let tiles = vec![
|
||||
wrap(Box::new(tiles::Load::new())),
|
||||
wrap(Box::new(tiles::Memory::new())),
|
||||
wrap(Box::new(tiles::Hostname::new())),
|
||||
wrap(Box::new(tiles::Time::new())),
|
||||
];
|
||||
|
||||
let tiles: Vec<tile::Tile> = config
|
||||
.tile
|
||||
.iter()
|
||||
.map(config::process_tile)
|
||||
.map(wrap)
|
||||
.collect();
|
||||
|
||||
let num_tiles = tiles.len();
|
||||
for tile in tiles.into_iter() {
|
||||
tile.spawn();
|
||||
}
|
||||
|
||||
match output::launch(num_tiles, receiver).await? {}
|
||||
match output::launch(num_tiles, receiver, config.default).await? {}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,14 @@
|
|||
use crate::config::DefaultSection;
|
||||
use crate::tile::TileData;
|
||||
use std::convert::Infallible;
|
||||
use tokio::io::{self, AsyncWriteExt};
|
||||
use tokio::sync::mpsc::Receiver;
|
||||
|
||||
pub async fn launch(num_tiles: usize, mut receiver: Receiver<TileData>) -> io::Result<Infallible> {
|
||||
pub async fn launch(
|
||||
num_tiles: usize,
|
||||
mut receiver: Receiver<TileData>,
|
||||
_default: DefaultSection,
|
||||
) -> io::Result<Infallible> {
|
||||
let mut stdout = io::stdout();
|
||||
stdout.write_all(b"{ \"version\": 1 }\n[").await?;
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use crate::config::TimeConfig;
|
||||
use crate::tile::{Block, BlockSender, TileModule};
|
||||
use async_trait::async_trait;
|
||||
use chrono::prelude::*;
|
||||
|
@ -16,6 +17,13 @@ impl Time {
|
|||
Default::default()
|
||||
}
|
||||
|
||||
pub fn from_config(config: &TimeConfig) -> Time {
|
||||
Time {
|
||||
format: config.format.clone(),
|
||||
short_format: config.short_format.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
fn send_time(&mut self, time: DateTime<Local>) -> Block {
|
||||
Block {
|
||||
full_text: time.format(&self.format).to_string().into(),
|
||||
|
|
Loading…
Reference in a new issue