Skip to content

Commit 5791ffe

Browse files
Merge pull request #7 from brummer-simon/document_everything
Add documentation
2 parents 323e880 + cdf9c8d commit 5791ffe

File tree

7 files changed

+247
-52
lines changed

7 files changed

+247
-52
lines changed

examples/async_usage/src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
use std::str::FromStr;
21
// This Source Code Form is subject to the terms of the Mozilla Public
32
// License, v. 2.0. If a copy of the MPL was not distributed with this
43
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
54
//
65
// Author: Simon Brummer ([email protected])
76

7+
use std::str::FromStr;
88
use std::thread::sleep;
99
use std::time::Duration;
1010

rustfmt.toml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@ wrap_comments = true
99
normalize_comments = true
1010

1111
# Import related
12-
reorder_imports = true
13-
group_imports = "StdExternalCrate"
1412
imports_granularity = "Module"
1513

1614
# Warning related

src/async_target.rs

Lines changed: 58 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,29 @@
44
//
55
// Author: Simon Brummer ([email protected])
66

7-
use std::thread::{spawn, JoinHandle};
8-
use std::time::Duration;
7+
//! Module contains utilities for asynchronous, iterative "Target" reachability checking.
8+
//!
9+
//! # Notes
10+
//! Requires crate to be configured with feature "async".
911
12+
use super::{CheckTargetError, Status, Target};
1013
use futures::future::{join, join_all, BoxFuture, FutureExt};
14+
use std::thread::{spawn, JoinHandle};
15+
use std::time::Duration;
1116
use tokio::runtime::{self};
1217
use tokio::select;
13-
use tokio::sync::watch::{
14-
Receiver, Sender, {self},
15-
};
18+
use tokio::sync::watch::{self, Receiver, Sender};
1619
use tokio::task::{self};
1720
use tokio::time::{self};
1821

19-
use crate::{CheckTargetError, Status, Target};
20-
22+
/// Alias on [Status] to distinct between status of previous availability
23+
/// check and the current availability check
2124
pub type OldStatus = Status;
2225

26+
/// Struct storing all data used during asynchronous execution.
27+
///
28+
/// For async check execution, wrap the instances of [Target] in [AsyncTarget] and hand them to
29+
/// [AsyncTargetExecutor::start].
2330
pub struct AsyncTarget<'a> {
2431
target: Box<dyn Target + Send + 'a>,
2532
check_handler: Box<dyn FnMut(&dyn Target, Status, OldStatus, Option<CheckTargetError>) + Send + 'a>,
@@ -28,6 +35,15 @@ pub struct AsyncTarget<'a> {
2835
}
2936

3037
impl<'a> AsyncTarget<'a> {
38+
/// Construct an [AsyncTarget]. For more convenience use [AsyncTarget::from] instead.
39+
///
40+
/// # Arguments
41+
/// * target: trait object implementing [Target] to use in periodic checks.
42+
/// * check_handler: Function to call with the results of [Target::check_availability].
43+
/// * check_interval: time [Duration] between periodic availability checks.
44+
///
45+
/// # Returns
46+
/// Instance of [AsyncTarget].
3147
pub fn new(
3248
target: Box<dyn Target + Send + 'a>,
3349
check_handler: Box<dyn FnMut(&dyn Target, Status, OldStatus, Option<CheckTargetError>) + Send + 'a>,
@@ -47,23 +63,57 @@ where
4763
T: Target + Send + 'a,
4864
U: FnMut(&dyn Target, Status, OldStatus, Option<CheckTargetError>) + Send + 'a,
4965
{
66+
/// Build a [AsyncTarget] from a Target, a function to be executed with the results of
67+
/// an availability check and a time interval an availability check occurs.
68+
///
69+
/// # Example
70+
/// See Example in [AsyncTargetExecutor::start]
5071
fn from(pieces: (T, U, Duration)) -> AsyncTarget<'a> {
5172
let (target, check_handler, check_interval) = pieces;
5273
AsyncTarget::new(Box::from(target), Box::from(check_handler), check_interval)
5374
}
5475
}
5576

77+
/// Async target check executor used to check the availability of a given number of [AsyncTarget]s.
5678
pub struct AsyncTargetExecutor {
79+
/// Optional threadhandle and synchronization channel to executing runtime.
5780
worker: Option<(JoinHandle<()>, Sender<()>)>,
5881
}
5982

6083
impl AsyncTargetExecutor {
84+
/// Construct a new [AsyncTargetExecutor]
6185
pub fn new() -> Self {
6286
AsyncTargetExecutor {
6387
worker: None,
6488
}
6589
}
6690

91+
/// Start periodic availability checks for all given targets
92+
///
93+
/// Each targets execution behavior is configured during [AsyncTarget] construction.
94+
///
95+
/// # Arguments
96+
/// * targets: a vector of [AsyncTarget]s, those availability should be check periodically.
97+
///
98+
/// # Example
99+
/// ```
100+
/// # use std::{str::FromStr, thread::sleep, time::Duration};
101+
/// # use reachable::*;
102+
///
103+
/// // Setup AsyncTarget
104+
/// let target = IcmpTarget::from_str("127.0.0.1").unwrap();
105+
/// let check_handler = |_: &dyn Target, _: Status, _: OldStatus, _: Option<CheckTargetError>| {
106+
/// // Handle check results
107+
/// };
108+
/// let check_interval = Duration::from_secs(1);
109+
/// let async_target = AsyncTarget::from((target, check_handler, check_interval));
110+
///
111+
/// // Setup AsyncTargetExecutor and let it run for 1s
112+
/// let mut exec = AsyncTargetExecutor::new();
113+
/// exec.start(vec![async_target]);
114+
/// sleep(Duration::from_secs(1));
115+
/// exec.stop();
116+
/// ```
67117
pub fn start(&mut self, targets: Vec<AsyncTarget<'static>>) {
68118
if self.worker.is_none() {
69119
// Setup teardown mechanism and construct runtime
@@ -92,6 +142,7 @@ impl AsyncTargetExecutor {
92142
}
93143
}
94144

145+
/// Stop asynchronous processing started with [AsyncTargetExecutor::start] gracefully.
95146
pub fn stop(&mut self) {
96147
if let Some((handle, teardown_send)) = self.worker.take() {
97148
// Signal all async tasks to terminate and wait until runtime thread stopped.

src/error.rs

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,29 @@
44
//
55
// Author: Simon Brummer ([email protected])
66

7+
//! Module containing all custom error types. All type shall implement [Error].
8+
9+
// Imports
710
use std::error::Error;
811
use std::fmt::{self};
912
use std::io::{self};
1013
use std::num::{self};
1114

12-
type ErrorMessage = &'static str;
15+
// Documentation imports
16+
#[cfg(doc)]
17+
use super::Target;
18+
19+
/// Alias for preallocated error messages
20+
pub type ErrorMessage = &'static str;
1321

14-
// ParseTargetError
22+
/// Custom error type for a failed attempt to parse something into a [Target].
1523
#[derive(Debug)]
1624
pub enum ParseTargetError {
1725
/// ParseTargetError containing a Message
1826
Message(ErrorMessage),
19-
/// ParseTargetError containing a Message and a ParseIntError
27+
/// ParseTargetError containing a Message and a [num::ParseIntError]
2028
ParseIntError(ErrorMessage, num::ParseIntError),
21-
/// ParseTargetError containing a Message and a trait object implementing Error
29+
/// ParseTargetError containing a Message and a trait object implementing [Error]
2230
GenericError(ErrorMessage, Box<dyn Error>),
2331
}
2432

@@ -73,14 +81,14 @@ impl From<Box<dyn Error>> for ParseTargetError {
7381
}
7482
}
7583

76-
// ResolveTargetError
84+
/// Custom error type for a failed attempt to resolve a [Target].
7785
#[derive(Debug)]
7886
pub enum ResolveTargetError {
7987
/// ResolveTargetError containing a Message
8088
Message(ErrorMessage),
81-
/// ResolveTargetError containing a Message and an io::Error
89+
/// ResolveTargetError containing a Message and an [io::Error]
8290
IoError(ErrorMessage, io::Error),
83-
/// CheckTargetError containing a Message and a trait object implementing Error
91+
/// ResolveTargetError containing a Message and a trait object implementing [Error]
8492
GenericError(ErrorMessage, Box<dyn Error>),
8593
}
8694

@@ -141,14 +149,14 @@ impl From<Box<dyn Error>> for ResolveTargetError {
141149
}
142150
}
143151

144-
// TargetCheckError
152+
/// Custom error type for a failed attempt to check the availability of a [Target].
145153
#[derive(Debug)]
146154
pub enum CheckTargetError {
147155
/// CheckTargetError containing a Message
148156
Message(ErrorMessage),
149-
/// CheckTargetError containing a Message and a ResolveTargetError
157+
/// CheckTargetError containing a Message and a [ResolveTargetError]
150158
ResolveTargetError(ErrorMessage, ResolveTargetError),
151-
/// CheckTargetError containing a Message and a trait object implementing Error
159+
/// CheckTargetError containing a Message and a trait object implementing [Error]
152160
GenericError(ErrorMessage, Box<dyn Error>),
153161
}
154162

src/lib.rs

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,27 @@
44
//
55
// Author: Simon Brummer ([email protected])
66

7-
mod error;
8-
pub use error::{CheckTargetError, ParseTargetError, ResolveTargetError};
9-
10-
mod resolve_policy;
11-
pub use resolve_policy::ResolvePolicy;
7+
//! Reachable, check if a Target is currently available or not.
8+
//!
9+
//! A "Target" is everything that implements the Target trait, used to
10+
//! check if, a resource is currently available. This crate offers a ICMP and TCP based Target
11+
//! usable to check, if a computer is available over the network.
12+
//!
13+
//! Additionally this crate contains asynchronous utilities to execute these checks regularly
14+
//! within a given time interval.
1215
13-
mod target;
14-
pub use target::{IcmpTarget, Status, Target, TcpTarget};
16+
// Modules
17+
pub mod error;
18+
pub mod resolve_policy;
19+
pub mod target;
1520

1621
#[cfg(feature = "async")]
17-
mod async_target;
22+
pub mod async_target;
23+
24+
// Re-exports
25+
pub use error::{CheckTargetError, ParseTargetError, ResolveTargetError};
26+
pub use resolve_policy::ResolvePolicy;
27+
pub use target::{Fqhn, IcmpTarget, Port, Status, Target, TcpTarget};
1828

1929
#[cfg(feature = "async")]
2030
pub use async_target::{AsyncTarget, AsyncTargetExecutor, OldStatus};

src/resolve_policy.rs

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,56 @@
44
//
55
// Author: Simon Brummer ([email protected])
66

7-
use std::net::IpAddr;
7+
//! Module containing everything related network name resolution and filtering
8+
//! of the resolved IP addresses.
89
10+
// Imports
11+
use super::ResolveTargetError;
912
use dns_lookup::lookup_host;
13+
use std::net::IpAddr;
1014

11-
use super::ResolveTargetError;
15+
// Documentation imports
16+
#[cfg(doc)]
17+
use super::{IcmpTarget, TcpTarget};
1218

19+
/// A ResolvePolicy allows control over IP address resolution of network targets
20+
/// like [IcmpTarget] and [TcpTarget].
1321
#[derive(PartialEq, Debug)]
1422
pub enum ResolvePolicy {
15-
/// Resolve FQHN IP version agnostic
23+
/// Resolve use all IP address versions
1624
Agnostic,
17-
/// Resolve FQHN to IPv4 addresses only
25+
/// Resolve to IPv4 addresses only
1826
ResolveToIPv4,
19-
/// Resolve FQHN to IPv6 addresses only
27+
/// Resolve to IPv6 addresses only
2028
ResolveToIPv6,
2129
}
2230

2331
impl ResolvePolicy {
32+
/// Resolve given "fully qualified domain name" (fancy name for a hostname or ip address)
33+
/// to a series of ip addresses associated with given fqhn.
34+
///
35+
/// # Arguments
36+
/// * fqhn: string containing "fully qualified domain name" e.g. "::1", "localhost".
37+
///
38+
/// # Returns
39+
/// * On success, vector containing all ip addresses the fqhn resolved to.
40+
/// * On failure, a [ResolveTargetError]. Either failed the name resolution itself or all
41+
/// addresses were filtered out according to [ResolvePolicy].
42+
///
43+
/// # Example
44+
/// ```
45+
/// # use std::net::{IpAddr, Ipv4Addr};
46+
/// # use reachable::ResolvePolicy;
47+
///
48+
/// // FQHN was resolved
49+
/// assert_eq!(
50+
/// ResolvePolicy::Agnostic.resolve("127.0.0.1").unwrap(),
51+
/// vec![IpAddr::V4(Ipv4Addr::LOCALHOST)]
52+
/// );
53+
///
54+
/// // FQHN was resolved, but all Addresses were filtered
55+
/// assert_eq!(ResolvePolicy::ResolveToIPv6.resolve("127.0.0.1").is_err(), true);
56+
/// ```
2457
pub fn resolve(&self, fqhn: &str) -> Result<Vec<IpAddr>, ResolveTargetError> {
2558
let mut addrs = lookup_host(fqhn)?;
2659

0 commit comments

Comments
 (0)