feat: Add Undistract Me Feature (#1019)

Often it is handy to get notified when the execution of a command finished.
This commit includes notify-rust in order to generate a desktop notification
when a command execution finished.
This commit is contained in:
Marc Schreiber 2020-08-11 18:44:25 +02:00 committed by GitHub
parent 93c568e118
commit 8c71eb5307
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 283 additions and 40 deletions

View File

@ -27,6 +27,9 @@ jobs:
profile: minimal profile: minimal
components: rustfmt components: rustfmt
- name: Setup | libdbus (ubuntu)
run: sudo apt-get install libdbus-1-dev
- name: Build | Format - name: Build | Format
run: cargo fmt --all -- --check run: cargo fmt --all -- --check
@ -51,6 +54,10 @@ jobs:
target target
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
- name: Setup | libdbus (ubuntu)
if: matrix.os == 'ubuntu-latest'
run: sudo apt-get install libdbus-1-dev
- name: Setup | Rust - name: Setup | Rust
uses: actions-rs/toolchain@v1 uses: actions-rs/toolchain@v1
with: with:
@ -108,6 +115,11 @@ jobs:
- name: Setup | Checkout - name: Setup | Checkout
uses: actions/checkout@v2 uses: actions/checkout@v2
- name: Setup | libdbus (ubuntu)
if: matrix.os == 'ubuntu-latest'
run: sudo apt-get install libdbus-1-dev
# Cache files between builds
- name: Setup | Cache Cargo - name: Setup | Cache Cargo
uses: actions/cache@v2 uses: actions/cache@v2
with: with:
@ -132,4 +144,4 @@ jobs:
# Run the ignored tests that expect the above setup # Run the ignored tests that expect the above setup
- name: Build | Test - name: Build | Test
run: cargo test -- -Z unstable-options --include-ignored run: cargo test --all-features -- -Z unstable-options --include-ignored

243
Cargo.lock generated
View File

@ -94,6 +94,12 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "bitflags"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5"
[[package]] [[package]]
name = "bitflags" name = "bitflags"
version = "1.2.1" version = "1.2.1"
@ -111,6 +117,12 @@ dependencies = [
"constant_time_eq", "constant_time_eq",
] ]
[[package]]
name = "block"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a"
[[package]] [[package]]
name = "block-buffer" name = "block-buffer"
version = "0.7.3" version = "0.7.3"
@ -187,13 +199,13 @@ dependencies = [
[[package]] [[package]]
name = "clap" name = "clap"
version = "2.33.1" version = "2.33.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bdfa80d47f954d53a35a64987ca1422f495b8d6483c0fe9f7117b36c2a792129" checksum = "10040cdf04294b565d9e0319955430099ec3813a64c952b86a41200ad714ae48"
dependencies = [ dependencies = [
"ansi_term 0.11.0", "ansi_term 0.11.0",
"atty", "atty",
"bitflags", "bitflags 1.2.1",
"strsim", "strsim",
"textwrap", "textwrap",
"unicode-width", "unicode-width",
@ -286,6 +298,16 @@ dependencies = [
"lazy_static", "lazy_static",
] ]
[[package]]
name = "dbus"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5cd9e78c210146a1860f897db03412fd5091fd73100778e43ee255cca252cf32"
dependencies = [
"libc",
"libdbus-sys",
]
[[package]] [[package]]
name = "digest" name = "digest"
version = "0.8.1" version = "0.8.1"
@ -295,6 +317,17 @@ dependencies = [
"generic-array", "generic-array",
] ]
[[package]]
name = "dirs"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fd78930633bd1c6e35c4b42b1df7b0cbc6bc191146e512bb3bedf243fcc3901"
dependencies = [
"libc",
"redox_users",
"winapi",
]
[[package]] [[package]]
name = "dirs-next" name = "dirs-next"
version = "1.0.1" version = "1.0.1"
@ -330,9 +363,9 @@ checksum = "134951f4028bdadb9b84baf4232681efbf277da25144b9b0ad65df75946c422b"
[[package]] [[package]]
name = "either" name = "either"
version = "1.5.3" version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3" checksum = "cd56b59865bce947ac5958779cfa508f6c3b9497cc762b7e24a12d11ccde2c4f"
[[package]] [[package]]
name = "env_logger" name = "env_logger"
@ -410,7 +443,7 @@ version = "0.13.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6ac22e49b7d886b6802c66662b12609452248b1bc9e87d6d83ecea3db96f557" checksum = "e6ac22e49b7d886b6802c66662b12609452248b1bc9e87d6d83ecea3db96f557"
dependencies = [ dependencies = [
"bitflags", "bitflags 1.2.1",
"libc", "libc",
"libgit2-sys", "libgit2-sys",
"log", "log",
@ -419,9 +452,9 @@ dependencies = [
[[package]] [[package]]
name = "hashbrown" name = "hashbrown"
version = "0.8.1" version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34f595585f103464d8d2f6e9864682d74c1601fed5e07d62b1c9058dba8246fb" checksum = "e91b62f79061a0bc2e046024cb7ba44b08419ed238ecbd9adbd787434b9e8c25"
dependencies = [ dependencies = [
"autocfg", "autocfg",
] ]
@ -468,9 +501,9 @@ dependencies = [
[[package]] [[package]]
name = "indexmap" name = "indexmap"
version = "1.5.0" version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b88cd59ee5f71fea89a62248fc8f387d44400cefe05ef548466d61ced9029a7" checksum = "86b45e59b16c76b11bf9738fd5d38879d3bd28ad292d7b313608becb17ae2df9"
dependencies = [ dependencies = [
"autocfg", "autocfg",
"hashbrown", "hashbrown",
@ -509,6 +542,15 @@ version = "0.2.74"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2f02823cf78b754822df5f7f268fb59822e7296276d3e069d8e8cb26a14bd10" checksum = "a2f02823cf78b754822df5f7f268fb59822e7296276d3e069d8e8cb26a14bd10"
[[package]]
name = "libdbus-sys"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc12a3bc971424edbbf7edaf6e5740483444db63aa8e23d3751ff12a30f306f0"
dependencies = [
"pkg-config",
]
[[package]] [[package]]
name = "libgit2-sys" name = "libgit2-sys"
version = "0.12.9+1.0.1" version = "0.12.9+1.0.1"
@ -548,6 +590,18 @@ dependencies = [
"cfg-if", "cfg-if",
] ]
[[package]]
name = "mac-notification-sys"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3dfb6b71a9a89cd38b395d994214297447e8e63b1ba5708a9a2b0b1048ceda76"
dependencies = [
"cc",
"chrono",
"dirs",
"objc-foundation",
]
[[package]] [[package]]
name = "mach" name = "mach"
version = "0.2.3" version = "0.2.3"
@ -557,6 +611,15 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "malloc_buf"
version = "0.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb"
dependencies = [
"libc",
]
[[package]] [[package]]
name = "maplit" name = "maplit"
version = "1.0.2" version = "1.0.2"
@ -614,7 +677,7 @@ version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b2e0b4f3320ed72aaedb9a5ac838690a8047c7b275da22711fddff4f8a14229" checksum = "3b2e0b4f3320ed72aaedb9a5ac838690a8047c7b275da22711fddff4f8a14229"
dependencies = [ dependencies = [
"bitflags", "bitflags 1.2.1",
"cc", "cc",
"cfg-if", "cfg-if",
"libc", "libc",
@ -627,12 +690,23 @@ version = "0.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83450fe6a6142ddd95fb064b746083fc4ef1705fe81f64a64e1d4b39f54a1055" checksum = "83450fe6a6142ddd95fb064b746083fc4ef1705fe81f64a64e1d4b39f54a1055"
dependencies = [ dependencies = [
"bitflags", "bitflags 1.2.1",
"cc", "cc",
"cfg-if", "cfg-if",
"libc", "libc",
] ]
[[package]]
name = "notify-rust"
version = "4.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "144acee6a0543dc74893e4b8a33936b5b0a94cc2d4ab024afd0c6daff7afc3c0"
dependencies = [
"dbus",
"mac-notification-sys",
"winrt-notification",
]
[[package]] [[package]]
name = "ntapi" name = "ntapi"
version = "0.3.4" version = "0.3.4"
@ -671,6 +745,35 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "objc"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1"
dependencies = [
"malloc_buf",
]
[[package]]
name = "objc-foundation"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9"
dependencies = [
"block",
"objc",
"objc_id",
]
[[package]]
name = "objc_id"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b"
dependencies = [
"objc",
]
[[package]] [[package]]
name = "once_cell" name = "once_cell"
version = "1.4.0" version = "1.4.0"
@ -698,7 +801,7 @@ version = "0.10.30"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d575eff3665419f9b83678ff2815858ad9d11567e082f5ac1814baba4e2bcb4" checksum = "8d575eff3665419f9b83678ff2815858ad9d11567e082f5ac1814baba4e2bcb4"
dependencies = [ dependencies = [
"bitflags", "bitflags 1.2.1",
"cfg-if", "cfg-if",
"foreign-types", "foreign-types",
"lazy_static", "lazy_static",
@ -786,8 +889,8 @@ dependencies = [
"pest", "pest",
"pest_meta", "pest_meta",
"proc-macro2", "proc-macro2",
"quote", "quote 1.0.7",
"syn", "syn 1.0.38",
] ]
[[package]] [[package]]
@ -829,7 +932,7 @@ version = "1.0.19"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04f5f085b5d71e2188cb8271e5da0161ad52c3f227a661a3c135fdf28e258b12" checksum = "04f5f085b5d71e2188cb8271e5da0161ad52c3f227a661a3c135fdf28e258b12"
dependencies = [ dependencies = [
"unicode-xid", "unicode-xid 0.2.1",
] ]
[[package]] [[package]]
@ -847,6 +950,12 @@ dependencies = [
"memchr", "memchr",
] ]
[[package]]
name = "quote"
version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
[[package]] [[package]]
name = "quote" name = "quote"
version = "1.0.7" version = "1.0.7"
@ -1006,7 +1115,7 @@ version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64808902d7d99f78eaddd2b4e2509713babc3dc3c85ad6f4c447680f3c01e535" checksum = "64808902d7d99f78eaddd2b4e2509713babc3dc3c85ad6f4c447680f3c01e535"
dependencies = [ dependencies = [
"bitflags", "bitflags 1.2.1",
"core-foundation 0.7.0", "core-foundation 0.7.0",
"core-foundation-sys 0.7.0", "core-foundation-sys 0.7.0",
"libc", "libc",
@ -1025,22 +1134,22 @@ dependencies = [
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.114" version = "1.0.115"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5317f7588f0a5078ee60ef675ef96735a1442132dc645eb1d12c018620ed8cd3" checksum = "e54c9a88f2da7238af84b5101443f0c0d0a3bbdc455e34a5c9497b1903ed55d5"
dependencies = [ dependencies = [
"serde_derive", "serde_derive",
] ]
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.114" version = "1.0.115"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a0be94b04690fbaed37cddffc5c134bf537c8e3329d53e982fe04c374978f8e" checksum = "609feed1d0a73cc36a0182a840a9b37b4a82f0b1150369f0536a9e3f2a31dc48"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote 1.0.7",
"syn", "syn 1.0.38",
] ]
[[package]] [[package]]
@ -1094,6 +1203,7 @@ dependencies = [
"log", "log",
"native-tls", "native-tls",
"nix 0.18.0", "nix 0.18.0",
"notify-rust",
"once_cell", "once_cell",
"open", "open",
"os_info", "os_info",
@ -1122,8 +1232,8 @@ name = "starship_module_config_derive"
version = "0.1.1" version = "0.1.1"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote 1.0.7",
"syn", "syn 1.0.38",
] ]
[[package]] [[package]]
@ -1133,14 +1243,50 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
[[package]] [[package]]
name = "syn" name = "strum"
version = "1.0.36" version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4cdb98bcb1f9d81d07b536179c269ea15999b5d14ea958196413869445bb5250" checksum = "4ca6e4730f517e041e547ffe23d29daab8de6b73af4b6ae2a002108169f5e7da"
[[package]]
name = "strum_macros"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3384590878eb0cab3b128e844412e2d010821e7e091211b9d87324173ada7db8"
dependencies = [
"quote 0.3.15",
"syn 0.11.11",
]
[[package]]
name = "syn"
version = "0.11.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad"
dependencies = [
"quote 0.3.15",
"synom",
"unicode-xid 0.0.4",
]
[[package]]
name = "syn"
version = "1.0.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e69abc24912995b3038597a7a593be5053eb0fb44f3cc5beec0deb421790c1f4"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote 1.0.7",
"unicode-xid", "unicode-xid 0.2.1",
]
[[package]]
name = "synom"
version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6"
dependencies = [
"unicode-xid 0.0.4",
] ]
[[package]] [[package]]
@ -1277,6 +1423,12 @@ version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
[[package]]
name = "unicode-xid"
version = "0.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc"
[[package]] [[package]]
name = "unicode-xid" name = "unicode-xid"
version = "0.2.1" version = "0.2.1"
@ -1371,6 +1523,37 @@ 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 = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "winrt"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e30cba82e22b083dc5a422c2ee77e20dc7927271a0dc981360c57c1453cb48d"
dependencies = [
"winapi",
]
[[package]]
name = "winrt-notification"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c31a65da50d792c6f9bd2e3216249566c4fb1d2d34f9b7d2d66d2e93f62a242"
dependencies = [
"strum",
"strum_macros",
"winapi",
"winrt",
"xml-rs",
]
[[package]]
name = "xml-rs"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1945e12e16b951721d7976520b0832496ef79c31602c7a29d950de79ba74621"
dependencies = [
"bitflags 0.9.1",
]
[[package]] [[package]]
name = "yaml-rust" name = "yaml-rust"
version = "0.4.4" version = "0.4.4"

View File

@ -58,6 +58,7 @@ open = "1.4.0"
unicode-width = "0.1.8" unicode-width = "0.1.8"
term_size = "0.3.2" term_size = "0.3.2"
quick-xml = "0.18.1" quick-xml = "0.18.1"
notify-rust = { version = "4.0.0", optional = true }
# Optional/http: # Optional/http:
attohttpc = { version = "0.15.0", optional = true, default-features = false, features = ["tls", "form"] } attohttpc = { version = "0.15.0", optional = true, default-features = false, features = ["tls", "form"] }

View File

@ -9,6 +9,8 @@ pub struct CmdDurationConfig<'a> {
pub style: &'a str, pub style: &'a str,
pub show_milliseconds: bool, pub show_milliseconds: bool,
pub disabled: bool, pub disabled: bool,
pub show_notifications: bool,
pub min_time_to_notify: i64,
} }
impl<'a> RootModuleConfig<'a> for CmdDurationConfig<'a> { impl<'a> RootModuleConfig<'a> for CmdDurationConfig<'a> {
@ -19,6 +21,8 @@ impl<'a> RootModuleConfig<'a> for CmdDurationConfig<'a> {
show_milliseconds: false, show_milliseconds: false,
style: "yellow bold", style: "yellow bold",
disabled: false, disabled: false,
show_notifications: false,
min_time_to_notify: 45_000,
} }
} }
} }

View File

@ -198,6 +198,10 @@ impl<'a> Context<'a> {
_ => Shell::Unknown, _ => Shell::Unknown,
} }
} }
pub fn get_cmd_duration(&self) -> Option<u128> {
self.properties.get("cmd_duration")?.parse::<u128>().ok()
}
} }
#[derive(Debug)] #[derive(Debug)]

View File

@ -11,13 +11,6 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
let mut module = context.new_module("cmd_duration"); let mut module = context.new_module("cmd_duration");
let config: CmdDurationConfig = CmdDurationConfig::try_load(module.config); let config: CmdDurationConfig = CmdDurationConfig::try_load(module.config);
let props = &context.properties;
let elapsed = props
.get("cmd_duration")
.unwrap_or(&"invalid_time".into())
.parse::<u128>()
.ok()?;
/* TODO: Once error handling is implemented, warn the user if their config /* TODO: Once error handling is implemented, warn the user if their config
min time is nonsensical */ min time is nonsensical */
if config.min_time < 0 { if config.min_time < 0 {
@ -28,7 +21,10 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
return None; return None;
} }
if elapsed < config.min_time as u128 { let elapsed = context.get_cmd_duration()?;
let config_min = config.min_time as u128;
if elapsed < config_min {
return None; return None;
} }
@ -53,7 +49,7 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
} }
}); });
Some(module) Some(undistract_me(module, &config, elapsed))
} }
// Render the time into a nice human-readable string // Render the time into a nice human-readable string
@ -86,6 +82,49 @@ fn render_time_component((component, suffix): (&u128, &&str)) -> String {
} }
} }
#[cfg(not(feature = "notify-rust"))]
fn undistract_me<'a, 'b>(
module: Module<'a>,
config: &'b CmdDurationConfig,
_elapsed: u128,
) -> Module<'a> {
if config.show_notifications {
log::debug!("This version of starship was built without notification support.");
}
module
}
#[cfg(feature = "notify-rust")]
fn undistract_me<'a, 'b>(
module: Module<'a>,
config: &'b CmdDurationConfig,
elapsed: u128,
) -> Module<'a> {
use ansi_term::{unstyle, ANSIStrings};
use notify_rust::{Notification, Timeout};
if config.show_notifications && config.min_time_to_notify as u128 <= elapsed {
let body = format!(
"Command execution {}",
unstyle(&ANSIStrings(&module.ansi_strings()))
);
let mut notification = Notification::new();
notification
.summary("Command finished")
.body(&body)
.icon("utilities-terminal")
.timeout(Timeout::Milliseconds(750));
if let Err(err) = notification.show() {
log::trace!("Cannot show notification: {}", err);
}
}
module
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;