tiles send to an mpsc directly, builds on stable rust
This commit is contained in:
parent
f85d9b4910
commit
b22089d58b
318
Cargo.lock
generated
318
Cargo.lock
generated
|
@ -50,17 +50,6 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-trait"
|
||||
version = "0.1.74"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.39",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
version = "0.2.14"
|
||||
|
@ -105,6 +94,12 @@ version = "1.3.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07"
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.14.0"
|
||||
|
@ -149,7 +144,7 @@ dependencies = [
|
|||
"js-sys",
|
||||
"num-traits",
|
||||
"wasm-bindgen",
|
||||
"windows-targets",
|
||||
"windows-targets 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -182,7 +177,7 @@ checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c"
|
|||
dependencies = [
|
||||
"ansi_term",
|
||||
"atty",
|
||||
"bitflags",
|
||||
"bitflags 1.3.2",
|
||||
"strsim",
|
||||
"textwrap",
|
||||
"unicode-width",
|
||||
|
@ -244,12 +239,45 @@ dependencies = [
|
|||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "env_logger"
|
||||
version = "0.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95b3f3e67048839cb0d0781f445682a35113da7121f7c949db0e2be96a4fbece"
|
||||
dependencies = [
|
||||
"humantime",
|
||||
"is-terminal",
|
||||
"log",
|
||||
"regex",
|
||||
"termcolor",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.3.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "eyre"
|
||||
version = "0.6.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6267a1fa6f59179ea4afc8e50fd8612a3cc60bc858f786ff877a4a8cb042799"
|
||||
dependencies = [
|
||||
"indenter",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fnv"
|
||||
version = "1.0.7"
|
||||
|
@ -265,43 +293,6 @@ dependencies = [
|
|||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.3.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da0290714b38af9b4a7b094b8a37086d1b4e61f2df9122c3cad2577669145335"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-executor",
|
||||
"futures-io",
|
||||
"futures-sink",
|
||||
"futures-task",
|
||||
"futures-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-async-stream"
|
||||
version = "0.2.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "379790776b0d953337df4ab7ecc51936c66ea112484cad7912907b1d34253ebf"
|
||||
dependencies = [
|
||||
"futures-async-stream-macro",
|
||||
"futures-core",
|
||||
"pin-project",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-async-stream-macro"
|
||||
version = "0.2.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5df2c13d48c8cb8a3ec093ede6f0f4482f327d7bb781120c5fb483ef0f17e758"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.39",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-channel"
|
||||
version = "0.3.29"
|
||||
|
@ -309,7 +300,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -318,34 +308,6 @@ version = "0.3.29"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c"
|
||||
|
||||
[[package]]
|
||||
name = "futures-executor"
|
||||
version = "0.3.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0f4fb8693db0cf099eadcca0efe2a5a22e4550f98ed16aba6c48700da29597bc"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-task",
|
||||
"futures-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-io"
|
||||
version = "0.3.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa"
|
||||
|
||||
[[package]]
|
||||
name = "futures-macro"
|
||||
version = "0.3.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.39",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-sink"
|
||||
version = "0.3.29"
|
||||
|
@ -364,16 +326,10 @@ version = "0.3.29"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
"futures-macro",
|
||||
"futures-sink",
|
||||
"futures-task",
|
||||
"memchr",
|
||||
"pin-project-lite",
|
||||
"pin-utils",
|
||||
"slab",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -476,6 +432,12 @@ version = "1.0.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
|
||||
|
||||
[[package]]
|
||||
name = "humantime"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
|
||||
|
||||
[[package]]
|
||||
name = "hyper"
|
||||
version = "0.14.27"
|
||||
|
@ -547,6 +509,12 @@ dependencies = [
|
|||
"unicode-normalization",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indenter"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683"
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.1.0"
|
||||
|
@ -572,6 +540,17 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "is-terminal"
|
||||
version = "0.4.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b"
|
||||
dependencies = [
|
||||
"hermit-abi 0.3.3",
|
||||
"rustix",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.10"
|
||||
|
@ -608,6 +587,12 @@ dependencies = [
|
|||
"pkg-config",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.4.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456"
|
||||
|
||||
[[package]]
|
||||
name = "local-ip-address"
|
||||
version = "0.5.6"
|
||||
|
@ -617,7 +602,7 @@ dependencies = [
|
|||
"libc",
|
||||
"neli",
|
||||
"thiserror",
|
||||
"windows-sys",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -667,7 +652,7 @@ checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09"
|
|||
dependencies = [
|
||||
"libc",
|
||||
"wasi",
|
||||
"windows-sys",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -782,26 +767,6 @@ dependencies = [
|
|||
"siphasher",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project"
|
||||
version = "1.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422"
|
||||
dependencies = [
|
||||
"pin-project-internal",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-internal"
|
||||
version = "1.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.39",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.13"
|
||||
|
@ -820,6 +785,16 @@ version = "0.3.27"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964"
|
||||
|
||||
[[package]]
|
||||
name = "pretty_env_logger"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "865724d4dbe39d9f3dd3b52b88d859d66bcb2d6a0acfd5ea68a65fb66d4bdc1c"
|
||||
dependencies = [
|
||||
"env_logger",
|
||||
"log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error"
|
||||
version = "1.0.4"
|
||||
|
@ -967,6 +942,19 @@ version = "0.1.23"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.38.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316"
|
||||
dependencies = [
|
||||
"bitflags 2.4.1",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls"
|
||||
version = "0.21.7"
|
||||
|
@ -1002,15 +990,15 @@ dependencies = [
|
|||
name = "rustybar"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"chrono",
|
||||
"chrono-tz",
|
||||
"dbus",
|
||||
"dbus-tokio",
|
||||
"futures",
|
||||
"futures-async-stream",
|
||||
"eyre",
|
||||
"local-ip-address",
|
||||
"log",
|
||||
"maxminddb",
|
||||
"pretty_env_logger",
|
||||
"reqwest",
|
||||
"serde",
|
||||
"serde_json",
|
||||
|
@ -1133,7 +1121,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1200,7 +1188,7 @@ version = "0.5.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 1.3.2",
|
||||
"core-foundation",
|
||||
"system-configuration-sys",
|
||||
]
|
||||
|
@ -1215,6 +1203,15 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ff1bc3d3f05aff0403e8ac0d92ced918ec05b666a43f83297ccef5bea8a3d449"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "textwrap"
|
||||
version = "0.11.0"
|
||||
|
@ -1273,7 +1270,7 @@ dependencies = [
|
|||
"pin-project-lite",
|
||||
"socket2 0.5.5",
|
||||
"tokio-macros",
|
||||
"windows-sys",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1571,6 +1568,15 @@ version = "0.4.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
|
@ -1583,7 +1589,7 @@ version = "0.51.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
"windows-targets 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1592,7 +1598,16 @@ version = "0.48.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
"windows-targets 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
|
||||
dependencies = [
|
||||
"windows-targets 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1601,13 +1616,28 @@ version = "0.48.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
"windows_aarch64_gnullvm 0.48.5",
|
||||
"windows_aarch64_msvc 0.48.5",
|
||||
"windows_i686_gnu 0.48.5",
|
||||
"windows_i686_msvc 0.48.5",
|
||||
"windows_x86_64_gnu 0.48.5",
|
||||
"windows_x86_64_gnullvm 0.48.5",
|
||||
"windows_x86_64_msvc 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm 0.52.0",
|
||||
"windows_aarch64_msvc 0.52.0",
|
||||
"windows_i686_gnu 0.52.0",
|
||||
"windows_i686_msvc 0.52.0",
|
||||
"windows_x86_64_gnu 0.52.0",
|
||||
"windows_x86_64_gnullvm 0.52.0",
|
||||
"windows_x86_64_msvc 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1616,42 +1646,84 @@ version = "0.48.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
|
||||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.5.26"
|
||||
|
@ -1668,5 +1740,5 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"windows-sys",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
|
|
@ -8,15 +8,15 @@ edition = "2018"
|
|||
check_latency = []
|
||||
|
||||
[dependencies]
|
||||
async-trait = "0.1"
|
||||
chrono = "0.4"
|
||||
chrono-tz = "0.8"
|
||||
dbus = "0.9"
|
||||
dbus-tokio = "0.7"
|
||||
futures = "0.3"
|
||||
futures-async-stream = "0.2"
|
||||
eyre = "0.6"
|
||||
local-ip-address = "0.5"
|
||||
log = "0.4"
|
||||
maxminddb = "0.23"
|
||||
pretty_env_logger = "0.5"
|
||||
reqwest = { version = "0.11", features = ["rustls-tls"], default-features = false }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
|
|
28
flake.lock
28
flake.lock
|
@ -1,33 +1,12 @@
|
|||
{
|
||||
"nodes": {
|
||||
"fenix": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
],
|
||||
"rust-analyzer-src": []
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1702189261,
|
||||
"narHash": "sha256-TN6gE1eZddDhAoRrScV6Wji1Nk3uqMIDjGwN5ZesAZk=",
|
||||
"owner": "nix-community",
|
||||
"repo": "fenix",
|
||||
"rev": "cae060dbaf53430bb2b549ced0affd54d40e6cee",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"repo": "fenix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1702206697,
|
||||
"narHash": "sha256-vE9oEx3Y8TO5MnWwFlmopjHd1JoEBno+EhsfUCq5iR8=",
|
||||
"lastModified": 1702272962,
|
||||
"narHash": "sha256-D+zHwkwPc6oYQ4G3A1HuadopqRwUY/JkMwHz1YF7j4Q=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "29d6c96900b9b576c2fb89491452f283aa979819",
|
||||
"rev": "e97b3e4186bcadf0ef1b6be22b8558eab1cdeb5d",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -39,7 +18,6 @@
|
|||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"fenix": "fenix",
|
||||
"nixpkgs": "nixpkgs",
|
||||
"utils": "utils"
|
||||
}
|
||||
|
|
37
flake.nix
37
flake.nix
|
@ -4,36 +4,24 @@
|
|||
inputs = {
|
||||
nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
|
||||
utils.url = "github:numtide/flake-utils";
|
||||
fenix = {
|
||||
url = "github:nix-community/fenix";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
# We don't need rust-analyzer so don't clone it
|
||||
inputs.rust-analyzer-src.follows = "";
|
||||
};
|
||||
};
|
||||
|
||||
outputs = { self, nixpkgs, utils, fenix }:
|
||||
outputs = { self, nixpkgs, utils }:
|
||||
let supportedSystems = [ "x86_64-linux" "aarch64-linux" ];
|
||||
in (utils.lib.eachSystem supportedSystems (system:
|
||||
let
|
||||
pkgs = import nixpkgs {
|
||||
inherit system;
|
||||
overlays = [ fenix.overlays.default ];
|
||||
};
|
||||
toolchain = pkgs.fenix.complete;
|
||||
rustPlatform =
|
||||
pkgs.makeRustPlatform { inherit (toolchain) cargo rustc; };
|
||||
let pkgs = import nixpkgs { inherit system; };
|
||||
in rec {
|
||||
packages.rustybar = rustPlatform.buildRustPackage {
|
||||
packages.rustybar = with pkgs;
|
||||
rustPlatform.buildRustPackage {
|
||||
name = "rustybar";
|
||||
version = "0.1";
|
||||
src = ./.;
|
||||
cargoLock.lockFile = ./Cargo.lock;
|
||||
doCheck = false;
|
||||
nativeBuildInputs = with pkgs; [ pkg-config ];
|
||||
buildInputs = with pkgs; [ dbus ];
|
||||
nativeBuildInputs = [ pkg-config ];
|
||||
buildInputs = [ dbus ];
|
||||
|
||||
meta = with pkgs.lib; {
|
||||
meta = with lib; {
|
||||
homepage = "https://github.com/mildlyfunctionalgays/rustybar";
|
||||
description = "swaybar/i3bar command in Rust";
|
||||
maintainers = with maintainers; [ artemist ];
|
||||
|
@ -52,12 +40,13 @@
|
|||
pkg-config
|
||||
dbus
|
||||
libfaketime
|
||||
toolchain.cargo
|
||||
toolchain.rustc
|
||||
toolchain.rustfmt
|
||||
toolchain.clippy
|
||||
rustPackages.cargo
|
||||
rustPackages.rustc
|
||||
rustPackages.rustfmt
|
||||
rustPackages.clippy
|
||||
];
|
||||
RUST_SRC_PATH = "${toolchain.rust-src}/lib/rustlib";
|
||||
RUST_SRC_PATH =
|
||||
"${rustPackages.rustPlatform.rustLibSrc}/lib/rustlib";
|
||||
};
|
||||
devShell = devShells.rustybar;
|
||||
|
||||
|
|
|
@ -1,50 +0,0 @@
|
|||
use async_trait::async_trait;
|
||||
use futures::stream::{self, BoxStream};
|
||||
|
||||
#[async_trait]
|
||||
pub trait AsyncIter {
|
||||
type Item;
|
||||
async fn next(&mut self) -> Option<Self::Item>;
|
||||
|
||||
fn into_stream<'a>(self) -> BoxStream<'a, Self::Item>
|
||||
where
|
||||
Self: Sized + Send + 'a,
|
||||
{
|
||||
Box::pin(stream::unfold(self, |mut iter| async {
|
||||
let value = iter.next().await?;
|
||||
Some((value, iter))
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
use futures::{executor, StreamExt};
|
||||
|
||||
struct Numbers(usize);
|
||||
impl Numbers {
|
||||
fn new() -> Self {
|
||||
Numbers(0)
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl AsyncIter for Numbers {
|
||||
type Item = usize;
|
||||
|
||||
async fn next(&mut self) -> Option<Self::Item> {
|
||||
self.0 = self.0.checked_add(1)?;
|
||||
Some(self.0)
|
||||
}
|
||||
}
|
||||
#[test]
|
||||
fn test_numbers() {
|
||||
let a = async {
|
||||
let vec1: Vec<_> = Numbers::new().into_stream().take(10).collect().await;
|
||||
let vec2: Vec<_> = (1..=10).into_iter().collect();
|
||||
assert_eq!(vec1, vec2);
|
||||
};
|
||||
executor::block_on(a);
|
||||
}
|
||||
}
|
132
src/config.rs
132
src/config.rs
|
@ -1,11 +1,14 @@
|
|||
use crate::output::OutputChannel;
|
||||
use crate::tile::TileData;
|
||||
use crate::tiles;
|
||||
use crate::tiles::TileResult;
|
||||
|
||||
use dbus::nonblock::SyncConnection;
|
||||
use futures::{stream::BoxStream, Stream};
|
||||
use log::error;
|
||||
use log::warn;
|
||||
use serde::{Deserialize, Deserializer};
|
||||
use smart_default::SmartDefault;
|
||||
use std::env::var;
|
||||
use std::io;
|
||||
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
|
@ -13,13 +16,14 @@ use std::time::Duration;
|
|||
use structopt::StructOpt;
|
||||
use tokio::fs::File;
|
||||
use tokio::io::AsyncReadExt;
|
||||
use tokio_stream::StreamExt;
|
||||
use tokio::sync::mpsc;
|
||||
use tokio::task::JoinHandle;
|
||||
|
||||
#[derive(Deserialize, Clone, Debug, Default)]
|
||||
#[serde(default)]
|
||||
pub struct Config {
|
||||
pub default: DefaultSection,
|
||||
pub tile: Box<[TileConfig]>,
|
||||
pub tile: Vec<TileConfig>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Clone, Debug, Default)]
|
||||
|
@ -27,7 +31,7 @@ pub struct DefaultSection {
|
|||
pub spacing: Option<u32>,
|
||||
}
|
||||
|
||||
fn deserialize_duration<'de, D>(deserializer: D) -> Result<Option<Duration>, D::Error>
|
||||
fn deserialize_duration<'de, D>(deserializer: D) -> Result<Duration, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
|
@ -41,24 +45,16 @@ where
|
|||
"ms" => Duration::from_secs_f64(number / 1000f64),
|
||||
_ => unimplemented!(),
|
||||
};
|
||||
Ok(Some(duration))
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Clone, Debug)]
|
||||
pub struct TileConfig {
|
||||
#[serde(flatten)]
|
||||
config_type: TileConfigType,
|
||||
#[serde(deserialize_with = "deserialize_duration", default)]
|
||||
update: Option<Duration>,
|
||||
Ok(duration)
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Clone, Debug)]
|
||||
#[serde(tag = "type", rename_all = "snake_case")]
|
||||
pub enum TileConfigType {
|
||||
pub enum TileConfig {
|
||||
Battery(BatteryConfig),
|
||||
Memory,
|
||||
Load,
|
||||
Hostname,
|
||||
Memory(MemoryConfig),
|
||||
Load(LoadConfig),
|
||||
Hostname(HostnameConfig),
|
||||
UtcTime(UtcTimeConfig),
|
||||
SystemTime(SystemTimeConfig),
|
||||
LocalTime(LocalTimeConfig),
|
||||
|
@ -71,6 +67,33 @@ pub enum TileConfigType {
|
|||
pub struct BatteryConfig {
|
||||
#[default("BAT0")]
|
||||
pub battery: Box<str>,
|
||||
#[serde(deserialize_with = "deserialize_duration")]
|
||||
#[default(_code = "Duration::from_secs(30)")]
|
||||
pub update: Duration,
|
||||
}
|
||||
|
||||
#[derive(SmartDefault, Deserialize, Clone, Debug)]
|
||||
#[serde(default)]
|
||||
pub struct MemoryConfig {
|
||||
#[serde(deserialize_with = "deserialize_duration")]
|
||||
#[default(_code = "Duration::from_secs(30)")]
|
||||
pub update: Duration,
|
||||
}
|
||||
|
||||
#[derive(SmartDefault, Deserialize, Clone, Debug)]
|
||||
#[serde(default)]
|
||||
pub struct LoadConfig {
|
||||
#[serde(deserialize_with = "deserialize_duration")]
|
||||
#[default(_code = "Duration::from_secs(30)")]
|
||||
pub update: Duration,
|
||||
}
|
||||
|
||||
#[derive(SmartDefault, Deserialize, Clone, Debug)]
|
||||
#[serde(default)]
|
||||
pub struct HostnameConfig {
|
||||
#[serde(deserialize_with = "deserialize_duration")]
|
||||
#[default(_code = "Duration::from_secs(3600)")]
|
||||
pub update: Duration,
|
||||
}
|
||||
|
||||
#[derive(SmartDefault, Deserialize, Clone, Debug)]
|
||||
|
@ -78,6 +101,9 @@ pub struct BatteryConfig {
|
|||
pub struct IwdConfig {
|
||||
#[default("wlan0")]
|
||||
pub interface: Box<str>,
|
||||
#[serde(deserialize_with = "deserialize_duration")]
|
||||
#[default(_code = "Duration::from_secs(5)")]
|
||||
pub update: Duration,
|
||||
}
|
||||
|
||||
#[derive(SmartDefault, Deserialize, Clone, Debug)]
|
||||
|
@ -87,6 +113,7 @@ pub struct UtcTimeConfig {
|
|||
pub format: Box<str>,
|
||||
#[default("%H:%M:%S")]
|
||||
pub short_format: Box<str>,
|
||||
// No update field, update on the minute or second
|
||||
}
|
||||
|
||||
#[derive(SmartDefault, Deserialize, Clone, Debug)]
|
||||
|
@ -96,6 +123,7 @@ pub struct SystemTimeConfig {
|
|||
pub format: Box<str>,
|
||||
#[default("%H:%M:%S %Z")]
|
||||
pub short_format: Box<str>,
|
||||
// No update field, update on the minute or second
|
||||
}
|
||||
|
||||
#[derive(SmartDefault, Deserialize, Clone, Debug)]
|
||||
|
@ -106,11 +134,13 @@ pub struct LocalTimeConfig {
|
|||
#[default("%H:%M:%S %Z")]
|
||||
pub short_format: Box<str>,
|
||||
pub geoip_path: Option<Box<Path>>,
|
||||
#[serde(deserialize_with = "deserialize_duration")]
|
||||
#[default(_code = "Duration::from_secs(3600)")]
|
||||
pub update_interval: Duration,
|
||||
pub fallback_zone: Option<Box<str>>,
|
||||
#[default("https://myip.wtf/text")]
|
||||
pub ip_addr_api: Box<str>,
|
||||
// No update field, update on the minute or second
|
||||
}
|
||||
|
||||
#[derive(SmartDefault, Deserialize, Clone, Debug)]
|
||||
|
@ -118,6 +148,7 @@ pub struct LocalTimeConfig {
|
|||
pub struct InternetTimeConfig {
|
||||
#[default(2)]
|
||||
pub precision: u8,
|
||||
// No update field, update on the, uuh, wtf is metric time
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
|
@ -131,7 +162,7 @@ struct Args {
|
|||
pub config: Option<PathBuf>,
|
||||
}
|
||||
|
||||
pub async fn read_config() -> Result<Config, Box<dyn std::error::Error>> {
|
||||
pub async fn read_config() -> eyre::Result<Config> {
|
||||
let args = Args::from_args();
|
||||
let config_path = match args.config {
|
||||
Some(config) => config,
|
||||
|
@ -147,10 +178,7 @@ pub async fn read_config() -> Result<Config, Box<dyn std::error::Error>> {
|
|||
.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"
|
||||
)));
|
||||
eyre::bail!("Could not find RUSTYBAR_CONFIG, XDG_CONFIG_HOME, or HOME environment variables");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -163,38 +191,28 @@ pub async fn read_config() -> Result<Config, Box<dyn std::error::Error>> {
|
|||
Ok(toml::from_str(std::str::from_utf8(&config_contents)?)?)
|
||||
}
|
||||
|
||||
pub fn process_tile(
|
||||
tile: &TileConfig,
|
||||
connection: &Arc<SyncConnection>,
|
||||
) -> BoxStream<'static, TileResult> {
|
||||
let five_secs = Duration::from_secs(5);
|
||||
match &tile.config_type {
|
||||
TileConfigType::Battery(c) => wrap(
|
||||
tiles::battery_stream(c.clone()),
|
||||
tile.update.or(Some(five_secs)),
|
||||
),
|
||||
TileConfigType::Hostname => wrap(tiles::hostname_stream(connection.as_ref()), tile.update),
|
||||
TileConfigType::Load => wrap(tiles::load_stream(), tile.update.or(Some(five_secs))),
|
||||
TileConfigType::Memory => wrap(tiles::memory_stream(), tile.update.or(Some(five_secs))),
|
||||
TileConfigType::UtcTime(c) => wrap(tiles::utc_time_stream(c.clone()), tile.update),
|
||||
TileConfigType::Iwd(c) => wrap(
|
||||
tiles::iwd_stream(connection.clone(), c.clone()),
|
||||
tile.update.or(Some(five_secs)),
|
||||
),
|
||||
TileConfigType::SystemTime(c) => wrap(tiles::system_time_stream(c.clone()), tile.update),
|
||||
TileConfigType::LocalTime(c) => wrap(tiles::local_time_stream(c.clone()), tile.update),
|
||||
TileConfigType::InternetTime(c) => {
|
||||
wrap(tiles::internet_time_stream(c.clone()), tile.update)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn wrap<'a, S>(stream: S, duration: Option<Duration>) -> BoxStream<'a, TileResult>
|
||||
where
|
||||
S: Stream<Item = TileResult> + Send + 'a,
|
||||
{
|
||||
match duration {
|
||||
Some(duration) => Box::pin(stream.throttle(duration)),
|
||||
None => Box::pin(stream),
|
||||
pub fn launch_tile(
|
||||
tile: TileConfig,
|
||||
sender: mpsc::Sender<TileData>,
|
||||
tile_id: usize,
|
||||
dbus_conn: Arc<SyncConnection>,
|
||||
) -> JoinHandle<()> {
|
||||
tokio::spawn(async move {
|
||||
let output_chan = OutputChannel::with_random_uuid(sender, tile_id);
|
||||
let result = match tile {
|
||||
TileConfig::Battery(c) => tiles::battery(c, output_chan).await,
|
||||
TileConfig::Hostname(c) => tiles::hostname(c, output_chan, dbus_conn).await,
|
||||
TileConfig::Load(c) => tiles::load(c, output_chan).await,
|
||||
TileConfig::Memory(c) => tiles::memory(c, output_chan).await,
|
||||
TileConfig::UtcTime(c) => tiles::utc_time(c, output_chan).await,
|
||||
TileConfig::Iwd(c) => tiles::iwd(c, output_chan, dbus_conn).await,
|
||||
TileConfig::SystemTime(c) => tiles::system_time(c, output_chan).await,
|
||||
TileConfig::LocalTime(c) => tiles::local_time(c, output_chan).await,
|
||||
TileConfig::InternetTime(c) => tiles::internet_time(c, output_chan).await,
|
||||
};
|
||||
match result {
|
||||
Ok(_) => warn!("Tile {} exited without error", tile_id),
|
||||
Err(e) => error!("Tile {} exited with error: {:?}", tile_id, e),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
57
src/main.rs
57
src/main.rs
|
@ -1,71 +1,38 @@
|
|||
#![feature(coroutines)]
|
||||
#![feature(never_type)]
|
||||
#![feature(proc_macro_hygiene)]
|
||||
#![feature(stmt_expr_attributes)]
|
||||
#![feature(ip)]
|
||||
|
||||
mod async_iter;
|
||||
mod config;
|
||||
mod output;
|
||||
mod tile;
|
||||
mod tiles;
|
||||
|
||||
use dbus_tokio::connection::new_system_sync;
|
||||
use futures::channel::mpsc::{channel, Sender};
|
||||
use futures::{stream::BoxStream, StreamExt};
|
||||
use std::fmt::Debug;
|
||||
use std::sync::Arc;
|
||||
use uuid::Uuid;
|
||||
|
||||
use tokio::sync::mpsc;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<!, Box<dyn std::error::Error>> {
|
||||
let config = config::read_config().await?;
|
||||
async fn main() -> eyre::Result<()> {
|
||||
let mut 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_system_sync()?;
|
||||
pretty_env_logger::init();
|
||||
|
||||
// Now start listening on our D-Bus connection
|
||||
let (resource, dbus_conn) = new_system_sync()?;
|
||||
tokio::spawn(async {
|
||||
let err = resource.await;
|
||||
panic!("Lost connection to D-Bus: {}", err);
|
||||
});
|
||||
|
||||
let (sender, receiver) = channel(1024);
|
||||
let (sender, receiver) = mpsc::channel(1024);
|
||||
|
||||
let tiles: Vec<_> = config
|
||||
.tile
|
||||
.iter()
|
||||
.map(|tile| config::process_tile(tile, &conn))
|
||||
.drain(..)
|
||||
.enumerate()
|
||||
.map(|(index, stream)| spawn_stream(index, stream, sender.clone()))
|
||||
.map(|(sender_id, tile)| {
|
||||
config::launch_tile(tile, sender.clone(), sender_id, dbus_conn.clone())
|
||||
})
|
||||
.collect();
|
||||
|
||||
let num_tiles = tiles.len();
|
||||
|
||||
drop(sender);
|
||||
|
||||
output::launch(num_tiles, receiver, config.default).await?
|
||||
}
|
||||
|
||||
fn spawn_stream<E: 'static>(
|
||||
index: usize,
|
||||
stream: BoxStream<'static, Result<tile::Block, E>>,
|
||||
sender: Sender<Result<tile::TileData, E>>,
|
||||
) where
|
||||
E: Debug + Send,
|
||||
{
|
||||
tokio::spawn(async move {
|
||||
let instance: Arc<str> = Uuid::new_v4().to_string().into();
|
||||
let stream = stream.map(|block: Result<_, _>| {
|
||||
Ok(block.map(|block| tile::TileData {
|
||||
block: tile::Block {
|
||||
instance: instance.clone(),
|
||||
..block
|
||||
},
|
||||
sender_id: index,
|
||||
}))
|
||||
});
|
||||
let future = stream.forward(sender);
|
||||
future.await
|
||||
});
|
||||
output::run(num_tiles, receiver).await
|
||||
}
|
||||
|
|
|
@ -1,25 +1,50 @@
|
|||
use crate::config::DefaultSection;
|
||||
use crate::tile::TileData;
|
||||
use futures::channel::mpsc::Receiver;
|
||||
use futures::StreamExt;
|
||||
use tokio::io::{self, AsyncWriteExt};
|
||||
use crate::tile::{Block, TileData};
|
||||
use eyre::OptionExt;
|
||||
use std::sync::Arc;
|
||||
use tokio::{
|
||||
io::{self, AsyncWriteExt},
|
||||
sync::mpsc,
|
||||
};
|
||||
use uuid::Uuid;
|
||||
|
||||
pub async fn launch<E>(
|
||||
num_tiles: usize,
|
||||
mut receiver: Receiver<Result<TileData, E>>,
|
||||
_default: DefaultSection,
|
||||
) -> io::Result<!>
|
||||
where
|
||||
E: Send + std::fmt::Debug,
|
||||
{
|
||||
pub struct OutputChannel {
|
||||
sender: mpsc::Sender<TileData>,
|
||||
sender_id: usize,
|
||||
instance: Arc<str>,
|
||||
}
|
||||
|
||||
impl OutputChannel {
|
||||
pub fn with_random_uuid(sender: mpsc::Sender<TileData>, sender_id: usize) -> Self {
|
||||
Self {
|
||||
sender,
|
||||
sender_id,
|
||||
instance: Uuid::new_v4().to_string().into(),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn send(&self, mut block: Block) -> Result<(), mpsc::error::SendError<TileData>> {
|
||||
block.instance = self.instance.clone();
|
||||
self.sender
|
||||
.send(TileData {
|
||||
block,
|
||||
sender_id: self.sender_id,
|
||||
})
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn run(num_tiles: usize, mut receiver: mpsc::Receiver<TileData>) -> eyre::Result<()> {
|
||||
let mut stdout = io::stdout();
|
||||
stdout.write_all(b"{ \"version\": 1 }\n[").await?;
|
||||
|
||||
let mut blocks = Vec::new();
|
||||
blocks.resize_with(num_tiles, Default::default);
|
||||
loop {
|
||||
match receiver.next().await.unwrap() {
|
||||
Ok(message) => {
|
||||
let message = receiver
|
||||
.recv()
|
||||
.await
|
||||
.ok_or_eyre("No more messages to recieve")?;
|
||||
|
||||
if message.sender_id < num_tiles {
|
||||
blocks[message.sender_id] = Some(message.block);
|
||||
} else {
|
||||
|
@ -30,9 +55,4 @@ where
|
|||
serialized.extend_from_slice(b",\n");
|
||||
stdout.write_all(&serialized).await?;
|
||||
}
|
||||
Err(err) => {
|
||||
eprintln!("Error in tile: {:?}", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
use crate::config::BatteryConfig;
|
||||
use crate::output::OutputChannel;
|
||||
use crate::tile::Block;
|
||||
use futures::future::try_join3;
|
||||
use futures_async_stream::try_stream;
|
||||
use std::error::Error;
|
||||
|
||||
use std::path::Path;
|
||||
use tokio::fs::{try_exists, File};
|
||||
use tokio::io::AsyncReadExt;
|
||||
use tokio::try_join;
|
||||
|
||||
#[try_stream(ok = Block, error = Box<dyn Error + Send + Sync>)]
|
||||
pub async fn battery_stream(config: BatteryConfig) {
|
||||
pub async fn battery(config: BatteryConfig, output: OutputChannel) -> eyre::Result<()> {
|
||||
let base_dir = Path::new("/sys/class/power_supply").join(&*config.battery);
|
||||
let file_prefix = if try_exists(base_dir.join("energy_now")).await? {
|
||||
"energy_"
|
||||
|
@ -18,6 +17,7 @@ pub async fn battery_stream(config: BatteryConfig) {
|
|||
let now_path = base_dir.join(file_prefix.to_owned() + "now");
|
||||
let full_path = base_dir.join(file_prefix.to_owned() + "full");
|
||||
|
||||
let mut interval = tokio::time::interval(config.update);
|
||||
loop {
|
||||
let charge_now = async {
|
||||
let mut raw = String::new();
|
||||
|
@ -26,7 +26,7 @@ pub async fn battery_stream(config: BatteryConfig) {
|
|||
.read_to_string(&mut raw)
|
||||
.await?;
|
||||
let charge: u32 = raw.trim_end().parse()?;
|
||||
Result::<_, Box<dyn Error + Send + Sync>>::Ok(charge)
|
||||
eyre::Result::<_>::Ok(charge)
|
||||
};
|
||||
let charge_total = async {
|
||||
let mut raw = String::new();
|
||||
|
@ -35,7 +35,7 @@ pub async fn battery_stream(config: BatteryConfig) {
|
|||
.read_to_string(&mut raw)
|
||||
.await?;
|
||||
let charge: u32 = raw.trim_end().parse()?;
|
||||
Result::<_, Box<dyn Error + Send + Sync>>::Ok(charge)
|
||||
eyre::Result::<_>::Ok(charge)
|
||||
};
|
||||
let status = async {
|
||||
let mut raw = String::new();
|
||||
|
@ -44,16 +44,19 @@ pub async fn battery_stream(config: BatteryConfig) {
|
|||
.read_to_string(&mut raw)
|
||||
.await?;
|
||||
raw.truncate(raw.trim_end().len());
|
||||
Result::<_, Box<dyn Error + Send + Sync>>::Ok(raw)
|
||||
eyre::Result::<_>::Ok(raw)
|
||||
};
|
||||
let (charge_now, charge_total, status) =
|
||||
try_join3(charge_now, charge_total, status).await?;
|
||||
let (charge_now, charge_total, status) = try_join!(charge_now, charge_total, status)?;
|
||||
let percentage = charge_now * 100 / charge_total;
|
||||
yield Block {
|
||||
output
|
||||
.send(Block {
|
||||
full_text: format!("{}% {}", percentage, status).into(),
|
||||
short_text: format!("{}%", percentage).into_boxed_str().into(),
|
||||
name: "battery".into(),
|
||||
..Default::default()
|
||||
};
|
||||
})
|
||||
.await?;
|
||||
|
||||
interval.tick().await;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,26 +1,34 @@
|
|||
use crate::config::HostnameConfig;
|
||||
use crate::output::OutputChannel;
|
||||
use crate::tile::Block;
|
||||
use crate::tiles::TileResult;
|
||||
use dbus::nonblock::stdintf::org_freedesktop_dbus::Properties;
|
||||
use dbus::nonblock::{Proxy, SyncConnection};
|
||||
use futures::stream::Stream;
|
||||
use futures_async_stream::try_stream;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
|
||||
pub fn hostname_stream(connection: &SyncConnection) -> impl Stream<Item = TileResult> {
|
||||
pub async fn hostname(
|
||||
config: HostnameConfig,
|
||||
output: OutputChannel,
|
||||
dbus_conn: Arc<SyncConnection>,
|
||||
) -> eyre::Result<()> {
|
||||
let proxy = Proxy::new(
|
||||
"org.freedesktop.hostname1",
|
||||
"/org/freedesktop/hostname1",
|
||||
Duration::from_secs(5),
|
||||
connection,
|
||||
dbus_conn,
|
||||
);
|
||||
let mut interval = tokio::time::interval(config.update);
|
||||
loop {
|
||||
let reply = proxy.get("org.freedesktop.hostname1", "Hostname");
|
||||
#[try_stream]
|
||||
async move {
|
||||
let hostname: String = reply.await?;
|
||||
yield Block {
|
||||
output
|
||||
.send(Block {
|
||||
full_text: hostname.into(),
|
||||
name: "hostname".into(),
|
||||
..Default::default()
|
||||
};
|
||||
})
|
||||
.await?;
|
||||
|
||||
interval.tick().await;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
use super::TileResult;
|
||||
use crate::config::InternetTimeConfig;
|
||||
use crate::output::OutputChannel;
|
||||
use crate::tile::Block;
|
||||
use chrono::prelude::*;
|
||||
use futures_async_stream::stream;
|
||||
use tokio::time::sleep;
|
||||
|
||||
#[stream(item = TileResult)]
|
||||
pub async fn internet_time_stream(config: InternetTimeConfig) {
|
||||
pub async fn internet_time(config: InternetTimeConfig, output: OutputChannel) -> eyre::Result<()> {
|
||||
// "BMT" is actually just UTC+1
|
||||
let offset = FixedOffset::east_opt(60 * 60).unwrap();
|
||||
let factor = 10f64.powi(config.precision.into());
|
||||
|
@ -17,7 +15,8 @@ pub async fn internet_time_stream(config: InternetTimeConfig) {
|
|||
let seconds =
|
||||
now.num_seconds_from_midnight() as f64 + (now.nanosecond() as f64) / 1_000_000_000f64;
|
||||
let internet_time = seconds / 86.4;
|
||||
yield Ok(Block {
|
||||
output
|
||||
.send(Block {
|
||||
full_text: format!(
|
||||
"@{time:0width$.prec$}",
|
||||
time = internet_time,
|
||||
|
@ -29,7 +28,8 @@ pub async fn internet_time_stream(config: InternetTimeConfig) {
|
|||
short_text: Some(format!("@{:03.0}", internet_time).into_boxed_str()),
|
||||
name: "internet_time".into(),
|
||||
..Default::default()
|
||||
});
|
||||
})
|
||||
.await?;
|
||||
|
||||
// In normal (non-metric) seconds
|
||||
let difference = (1f64 - (internet_time * factor).fract()) / factor * 86.4;
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
use crate::config::IwdConfig;
|
||||
use crate::output::OutputChannel;
|
||||
use crate::tile::Block;
|
||||
use crate::tiles::TileResult;
|
||||
use dbus::arg::{PropMap, RefArg};
|
||||
use dbus::nonblock::stdintf::org_freedesktop_dbus::ObjectManager;
|
||||
use dbus::nonblock::{Proxy, SyncConnection};
|
||||
use dbus::Path;
|
||||
use futures::stream::Stream;
|
||||
use futures_async_stream::try_stream;
|
||||
use eyre::OptionExt;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
|
@ -29,17 +28,18 @@ fn get_interface_path(
|
|||
None
|
||||
}
|
||||
|
||||
pub fn iwd_stream(
|
||||
connection: Arc<SyncConnection>,
|
||||
pub async fn iwd(
|
||||
config: IwdConfig,
|
||||
) -> impl Stream<Item = TileResult> {
|
||||
let root_proxy = Proxy::new("net.connman.iwd", "/", Duration::from_secs(5), connection);
|
||||
#[try_stream]
|
||||
async move {
|
||||
output: OutputChannel,
|
||||
dbus_conn: Arc<SyncConnection>,
|
||||
) -> eyre::Result<()> {
|
||||
let root_proxy = Proxy::new("net.connman.iwd", "/", Duration::from_secs(5), dbus_conn);
|
||||
|
||||
let mut interval = tokio::time::interval(config.update);
|
||||
loop {
|
||||
let managed_objects = root_proxy.get_managed_objects().await?;
|
||||
let interface_path = get_interface_path(&managed_objects, &config.interface)
|
||||
.ok_or("Couldn't find interface")?;
|
||||
.ok_or_eyre("Couldn't find interface")?;
|
||||
let station_path = managed_objects
|
||||
.get(&interface_path)
|
||||
.and_then(|object| object.get("net.connman.iwd.Station"))
|
||||
|
@ -52,16 +52,19 @@ pub fn iwd_stream(
|
|||
.and_then(|object| object.get("net.connman.iwd.Network"))
|
||||
.and_then(|network| network.get("Name"))
|
||||
.and_then(|name| name.as_str())
|
||||
.ok_or("Unable to get network name")?;
|
||||
.ok_or_eyre("Unable to get network name")?;
|
||||
format!("{}: {}", &config.interface, network_name)
|
||||
} else {
|
||||
format!("{}: disconnected", &config.interface)
|
||||
};
|
||||
yield Block {
|
||||
output
|
||||
.send(Block {
|
||||
full_text: text.into(),
|
||||
name: config.interface.clone(),
|
||||
..Default::default()
|
||||
};
|
||||
}
|
||||
})
|
||||
.await?;
|
||||
|
||||
interval.tick().await;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,20 +1,24 @@
|
|||
use crate::config::LoadConfig;
|
||||
use crate::output::OutputChannel;
|
||||
use crate::tile::Block;
|
||||
use futures_async_stream::try_stream;
|
||||
use std::error::Error;
|
||||
use tokio::fs::File;
|
||||
use tokio::io::AsyncReadExt;
|
||||
|
||||
#[try_stream(ok = Block, error = Box<dyn Error + Send + Sync>)]
|
||||
pub async fn load_stream() {
|
||||
pub async fn load(config: LoadConfig, output: OutputChannel) -> eyre::Result<()> {
|
||||
let mut interval = tokio::time::interval(config.update);
|
||||
loop {
|
||||
let mut raw = String::new();
|
||||
let mut file = File::open("/proc/loadavg").await?;
|
||||
file.read_to_string(&mut raw).await?;
|
||||
let (load, _rest) = raw.split_at(raw.find(' ').unwrap_or(0));
|
||||
yield Block {
|
||||
output
|
||||
.send(Block {
|
||||
full_text: load.into(),
|
||||
name: "load".into(),
|
||||
..Default::default()
|
||||
};
|
||||
})
|
||||
.await?;
|
||||
|
||||
interval.tick().await;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
use crate::config::LocalTimeConfig;
|
||||
use crate::output::OutputChannel;
|
||||
use crate::tile::Block;
|
||||
use chrono::prelude::*;
|
||||
use futures_async_stream::try_stream;
|
||||
use maxminddb::geoip2;
|
||||
use std::error::Error;
|
||||
|
||||
use std::net::IpAddr;
|
||||
use std::str::FromStr;
|
||||
use tokio::sync::watch;
|
||||
|
@ -13,10 +13,7 @@ struct State {
|
|||
pub tz: Option<chrono_tz::Tz>,
|
||||
}
|
||||
|
||||
async fn request_ipv4(
|
||||
client: &reqwest::Client,
|
||||
api: &str,
|
||||
) -> Result<IpAddr, Box<dyn Error + Send + Sync>> {
|
||||
async fn request_ipv4(client: &reqwest::Client, api: &str) -> eyre::Result<IpAddr> {
|
||||
let response = client.get(api).send().await?;
|
||||
let text = response.text().await?;
|
||||
Ok(IpAddr::from_str(text.trim())?)
|
||||
|
@ -28,16 +25,10 @@ fn lookup_timezone(db: &maxminddb::Reader<Vec<u8>>, addr: Option<IpAddr>) -> Opt
|
|||
chrono_tz::Tz::from_str(tz_name).ok()
|
||||
}
|
||||
|
||||
async fn find_time_zone(
|
||||
config: LocalTimeConfig,
|
||||
sender: watch::Sender<State>,
|
||||
) -> Result<!, Box<dyn std::error::Error + Send + Sync>> {
|
||||
async fn find_time_zone(config: LocalTimeConfig, sender: watch::Sender<State>) -> eyre::Result<()> {
|
||||
// TODO: Add error messages;
|
||||
let Some(geoip_path) = &config.geoip_path else {
|
||||
return Err(Box::new(std::io::Error::new(
|
||||
std::io::ErrorKind::NotFound,
|
||||
"geoip path not specified",
|
||||
)));
|
||||
eyre::bail!("geoip path not specified");
|
||||
};
|
||||
let db_reader = maxminddb::Reader::open_readfile(geoip_path)?;
|
||||
|
||||
|
@ -75,10 +66,9 @@ async fn find_time_zone(
|
|||
}
|
||||
}
|
||||
|
||||
#[try_stream(ok = Block, error = Box<dyn Error + Send + Sync>)]
|
||||
pub async fn local_time_stream(config: LocalTimeConfig) {
|
||||
pub async fn local_time(config: LocalTimeConfig, output: OutputChannel) -> eyre::Result<()> {
|
||||
let fallback_tz = if let Some(tz_name) = &config.fallback_zone {
|
||||
Some(chrono_tz::Tz::from_str(tz_name)?)
|
||||
chrono_tz::Tz::from_str(tz_name).ok()
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
@ -92,19 +82,25 @@ pub async fn local_time_stream(config: LocalTimeConfig) {
|
|||
|
||||
if tz_thread.is_finished() {
|
||||
tz_thread.await??;
|
||||
eyre::bail!("timezone thread finished");
|
||||
}
|
||||
|
||||
if let Some(tz) = {
|
||||
// We're blocking the tz thread while we have the ref, so keep it as short as possible
|
||||
let maybe_tz = {
|
||||
let state = receiver.borrow_and_update();
|
||||
state.tz
|
||||
} {
|
||||
};
|
||||
|
||||
if let Some(tz) = maybe_tz {
|
||||
let local_now = utc_now.with_timezone(&tz);
|
||||
yield Block {
|
||||
output
|
||||
.send(Block {
|
||||
full_text: local_now.format(&config.format).to_string().into(),
|
||||
short_text: Some(local_now.format(&config.short_format).to_string().into()),
|
||||
name: "local_time".into(),
|
||||
..Default::default()
|
||||
};
|
||||
})
|
||||
.await?;
|
||||
}
|
||||
// It would take more resources to get time again, and we want to err on the side of
|
||||
// "wait a few µs too long" rather than too short.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::config::MemoryConfig;
|
||||
use crate::output::OutputChannel;
|
||||
use crate::tile::Block;
|
||||
use futures_async_stream::try_stream;
|
||||
use std::error::Error;
|
||||
use std::{io, str, u64};
|
||||
use tokio::fs::File;
|
||||
use tokio::io::AsyncReadExt;
|
||||
|
@ -18,7 +18,7 @@ fn prettify_kib(kib: u64) -> Box<str> {
|
|||
format!("{} {}iB", mem, unit).into_boxed_str()
|
||||
}
|
||||
|
||||
fn extract_value(line: &str) -> Result<u64, Box<dyn std::error::Error + Send + Sync>> {
|
||||
fn extract_value(line: &str) -> eyre::Result<u64> {
|
||||
let mut parts = line.split_whitespace();
|
||||
parts.next();
|
||||
Ok(parts
|
||||
|
@ -27,8 +27,8 @@ fn extract_value(line: &str) -> Result<u64, Box<dyn std::error::Error + Send + S
|
|||
.parse()?)
|
||||
}
|
||||
|
||||
#[try_stream(ok = Block, error = Box<dyn Error + Send + Sync>)]
|
||||
pub async fn memory_stream() {
|
||||
pub async fn memory(config: MemoryConfig, output: OutputChannel) -> eyre::Result<()> {
|
||||
let mut interval = tokio::time::interval(config.update);
|
||||
loop {
|
||||
let mut raw = [0u8; 256];
|
||||
let mut file = File::open("/proc/meminfo").await?;
|
||||
|
@ -50,11 +50,15 @@ pub async fn memory_stream() {
|
|||
let full_text = format!("{} avail / {}", mem_avail, mem_total).into_boxed_str();
|
||||
let short_text = format!("{} / {}", mem_avail, mem_total).into_boxed_str();
|
||||
|
||||
yield Block {
|
||||
output
|
||||
.send(Block {
|
||||
full_text,
|
||||
short_text: Some(short_text),
|
||||
name: "memory".into(),
|
||||
..Default::default()
|
||||
};
|
||||
})
|
||||
.await?;
|
||||
|
||||
interval.tick().await;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,17 +7,12 @@ pub mod local_time;
|
|||
pub mod memory;
|
||||
pub mod system_time;
|
||||
pub mod utc_time;
|
||||
pub use battery::battery_stream;
|
||||
pub use hostname::hostname_stream;
|
||||
pub use internet_time::internet_time_stream;
|
||||
pub use iwd::iwd_stream;
|
||||
pub use load::load_stream;
|
||||
pub use local_time::local_time_stream;
|
||||
pub use memory::memory_stream;
|
||||
pub use system_time::system_time_stream;
|
||||
pub use utc_time::utc_time_stream;
|
||||
|
||||
use crate::tile::Block;
|
||||
use std::error::Error;
|
||||
|
||||
pub type TileResult = Result<Block, Box<dyn Error + Send + Sync>>;
|
||||
pub use battery::battery;
|
||||
pub use hostname::hostname;
|
||||
pub use internet_time::internet_time;
|
||||
pub use iwd::iwd;
|
||||
pub use load::load;
|
||||
pub use local_time::local_time;
|
||||
pub use memory::memory;
|
||||
pub use system_time::system_time;
|
||||
pub use utc_time::utc_time;
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
use super::TileResult;
|
||||
use crate::config::SystemTimeConfig;
|
||||
use crate::output::OutputChannel;
|
||||
use crate::tile::Block;
|
||||
use chrono::prelude::*;
|
||||
use futures_async_stream::stream;
|
||||
use tokio::time::sleep;
|
||||
|
||||
#[stream(item = TileResult)]
|
||||
pub async fn system_time_stream(config: SystemTimeConfig) {
|
||||
pub async fn system_time(config: SystemTimeConfig, output: OutputChannel) -> eyre::Result<()> {
|
||||
loop {
|
||||
let now = Local::now();
|
||||
yield Ok(Block {
|
||||
output
|
||||
.send(Block {
|
||||
full_text: now.format(&config.format).to_string().into(),
|
||||
short_text: Some(now.format(&config.short_format).to_string().into()),
|
||||
name: "system_time".into(),
|
||||
..Default::default()
|
||||
});
|
||||
})
|
||||
.await?;
|
||||
|
||||
// It would take more resources to get time again, and we want to err on the side of
|
||||
// "wait a few µs too long" rather than too short.
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
use super::TileResult;
|
||||
use crate::config::UtcTimeConfig;
|
||||
use crate::output::OutputChannel;
|
||||
use crate::tile::Block;
|
||||
use chrono::prelude::*;
|
||||
use futures_async_stream::stream;
|
||||
use tokio::time::sleep;
|
||||
|
||||
#[stream(item = TileResult)]
|
||||
pub async fn utc_time_stream(config: UtcTimeConfig) {
|
||||
pub async fn utc_time(config: UtcTimeConfig, output: OutputChannel) -> eyre::Result<()> {
|
||||
loop {
|
||||
let now = Utc::now();
|
||||
yield Ok(Block {
|
||||
output
|
||||
.send(Block {
|
||||
full_text: now.format(&config.format).to_string().into(),
|
||||
short_text: Some(now.format(&config.short_format).to_string().into()),
|
||||
name: "utc_time".into(),
|
||||
..Default::default()
|
||||
});
|
||||
})
|
||||
.await?;
|
||||
|
||||
// It would take more resources to get time again, and we want to err on the side of
|
||||
// "wait a few µs too long" rather than too short.
|
||||
|
|
Loading…
Reference in a new issue