Skip to content

Commit 323e880

Browse files
committed
Initial commit
1 parent fcc997b commit 323e880

File tree

15 files changed

+1883
-675
lines changed

15 files changed

+1883
-675
lines changed

Cargo.toml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
[package]
2+
name = "reachable"
3+
version = "0.2.0"
4+
edition = "2021"
5+
authors = ["Simon Brummer <[email protected]>"]
6+
description = "Check if a Target (ICMP, TCP, custom) is reachable."
7+
license = "MPL-2.0"
8+
readme = "README.md"
9+
repository = "https://github.com/brummer-simon/reachable.git"
10+
keywords = ["network", "async"]
11+
categories = ["network-programming"]
12+
13+
[dependencies]
14+
dns-lookup = {version = "1.0.7"}
15+
futures = {version = "0.3.17", optional = true}
16+
tokio = {version = "1.12.0", optional = true, features = ["rt-multi-thread", "sync", "time", "macros"]}
17+
18+
[dev-dependencies]
19+
mockall = {version = "0.10.2"}
20+
21+
[features]
22+
default = ["async"]
23+
async = ["futures", "tokio"]
24+
25+
[workspace]
26+
members = [
27+
"examples/usage",
28+
"examples/async_usage",
29+
"examples/async_usage_custom_target",
30+
]

LICENSE

Lines changed: 373 additions & 674 deletions
Large diffs are not rendered by default.

README.md

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,47 @@
11
# reachable
2-
Rust crate to check if a system is reachable over the network.
2+
3+
Rust crate to check if a "Target" is available. The crate comes with the trait
4+
"Target" and ICMP/TCP based implementations of it. Additionally, the crate offers
5+
an async task Executor to perform availability checks of "Targets" on a regular basis.
6+
7+
## Usage
8+
9+
With this crate you can easily check if a computer is currently reachable over the network.
10+
Since all targets are implementations of trait "Target" the entire behavior is customizable.
11+
For example, it is easy to implement a custom Target to check if a Process is
12+
running or not.
13+
14+
## Example (from examples/async_usage/src/main.rs)
15+
16+
```rust
17+
use std::str::FromStr;
18+
use std::thread::sleep;
19+
use std::time::Duration;
20+
21+
use reachable::*;
22+
23+
fn main() {
24+
// Setup AsyncTargets
25+
let icmp_target = IcmpTarget::from_str("www.google.de").unwrap();
26+
let tcp_target = TcpTarget::from_str("www.google.de:80").unwrap();
27+
28+
let handler = |target: &dyn Target, status, old_status, error| {
29+
print!("Target \"{}\"", target.get_id());
30+
print!(", old status \"{}\"", old_status);
31+
print!(", new status \"{}\"", status);
32+
match error {
33+
None => println!(""),
34+
Some(err) => println!(", Error: \"{}\"", err),
35+
}
36+
};
37+
38+
// Spawn Async executor
39+
let mut exec = AsyncTargetExecutor::new();
40+
exec.start(vec![
41+
AsyncTarget::from((icmp_target, handler, Duration::from_secs(1))),
42+
AsyncTarget::from((tcp_target, handler, Duration::from_secs(1))),
43+
]);
44+
sleep(Duration::from_secs(3));
45+
exec.stop();
46+
}
47+
```

examples/async_usage/Cargo.toml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[package]
2+
name = "async_usage"
3+
version = "0.1.0"
4+
edition = "2021"
5+
authors = ["Simon Brummer <[email protected]>"]
6+
license = "MPL-2.0"
7+
description = "Example: async usage of reachable"
8+
9+
[dependencies]
10+
reachable = {path = "../..", features = ["async"]}

examples/async_usage/src/main.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
use std::str::FromStr;
2+
// This Source Code Form is subject to the terms of the Mozilla Public
3+
// License, v. 2.0. If a copy of the MPL was not distributed with this
4+
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
5+
//
6+
// Author: Simon Brummer ([email protected])
7+
8+
use std::thread::sleep;
9+
use std::time::Duration;
10+
11+
use reachable::*;
12+
13+
fn main() {
14+
// Setup AsyncTargets
15+
let icmp_target = IcmpTarget::from_str("www.google.de").unwrap();
16+
let tcp_target = TcpTarget::from_str("www.google.de:80").unwrap();
17+
18+
let handler = |target: &dyn Target, status, old_status, error| {
19+
print!("Target \"{}\"", target.get_id());
20+
print!(", old status \"{}\"", old_status);
21+
print!(", new status \"{}\"", status);
22+
match error {
23+
None => println!(""),
24+
Some(err) => println!(", Error: \"{}\"", err),
25+
}
26+
};
27+
28+
// Spawn Async executor
29+
let mut exec = AsyncTargetExecutor::new();
30+
exec.start(vec![
31+
AsyncTarget::from((icmp_target, handler, Duration::from_secs(1))),
32+
AsyncTarget::from((tcp_target, handler, Duration::from_secs(1))),
33+
]);
34+
sleep(Duration::from_secs(3));
35+
exec.stop();
36+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[package]
2+
name = "async_usage_custom_target"
3+
version = "0.1.0"
4+
edition = "2021"
5+
authors = ["Simon Brummer <[email protected]>"]
6+
license = "MPL-2.0"
7+
description = "Example: async usage of reachable with custom target"
8+
9+
[dependencies]
10+
reachable = {path = "../..", features = ["async"]}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// This Source Code Form is subject to the terms of the Mozilla Public
2+
// License, v. 2.0. If a copy of the MPL was not distributed with this
3+
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
4+
//
5+
// Author: Simon Brummer ([email protected])
6+
7+
use std::thread::sleep;
8+
use std::time::Duration;
9+
10+
use reachable::*;
11+
12+
struct MyTarget;
13+
14+
// Implement trait Target for custom type
15+
impl Target for MyTarget {
16+
fn get_id(&self) -> String {
17+
String::from("MyTarget")
18+
}
19+
20+
fn check_availability(&self) -> Result<Status, CheckTargetError> {
21+
Ok(Status::Available)
22+
}
23+
}
24+
25+
fn main() {
26+
// Setup custom Target for async availability check execution
27+
let my_target = MyTarget {};
28+
29+
let handler = |target: &dyn Target, status, old_status, _error| {
30+
print!("Target \"{}\"", target.get_id());
31+
print!(", old status \"{}\"", old_status);
32+
println!(", new status \"{}\"", status);
33+
};
34+
35+
let targets = vec![AsyncTarget::from((my_target, handler, Duration::from_secs(1)))];
36+
37+
// Spawn async executor
38+
let mut exec = AsyncTargetExecutor::new();
39+
exec.start(targets);
40+
sleep(Duration::from_secs(3));
41+
exec.stop();
42+
}

examples/usage/Cargo.toml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[package]
2+
name = "usage"
3+
version = "0.1.0"
4+
edition = "2021"
5+
authors = ["Simon Brummer <[email protected]>"]
6+
license = "MPL-2.0"
7+
description = "Example: usage of reachable"
8+
9+
[dependencies]
10+
reachable = {path = "../.."}

examples/usage/src/main.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// This Source Code Form is subject to the terms of the Mozilla Public
2+
// License, v. 2.0. If a copy of the MPL was not distributed with this
3+
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
4+
//
5+
// Author: Simon Brummer ([email protected])
6+
7+
use std::str::FromStr;
8+
9+
use reachable::*;
10+
11+
fn main() {
12+
// Construct ICMP Target and if its availability
13+
let icmp_target = IcmpTarget::from_str("www.google.de").unwrap();
14+
match icmp_target.check_availability() {
15+
Ok(status) => println!("{} is {}", icmp_target.get_id(), status),
16+
Err(error) => println!("Check failed for {} reason {}", icmp_target.get_id(), error),
17+
}
18+
}

rustfmt.toml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# General formatting
2+
max_width = 120
3+
empty_item_single_line = false
4+
struct_lit_single_line = false
5+
6+
# Comment related
7+
comment_width = 120
8+
wrap_comments = true
9+
normalize_comments = true
10+
11+
# Import related
12+
reorder_imports = true
13+
group_imports = "StdExternalCrate"
14+
imports_granularity = "Module"
15+
16+
# Warning related
17+
report_fixme = "Always"
18+
report_todo = "Always"

0 commit comments

Comments
 (0)