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