Struct ClockBoundClient

Source
pub struct ClockBoundClient { /* private fields */ }
Expand description

A structure for holding a client to communicate with ClockBoundD.

Implementations§

Source§

impl ClockBoundClient

Source

pub fn new() -> Result<ClockBoundClient, ClockBoundCError>

Create a new ClockBoundClient using the default clockboundd.sock path at “/run/clockboundd/clockboundd.sock”.

§Examples
use clock_bound_c::ClockBoundClient;
let client = match ClockBoundClient::new(){
    Ok(client) => client,
    Err(e) => {
        println!("Couldn't create client: {}", e);
        return
    }
};
Source

pub fn new_with_path( clock_bound_d_socket: PathBuf, ) -> Result<ClockBoundClient, ClockBoundCError>

Create a new ClockBoundClient using a defined clockboundd.sock path.

The expected default socket path is at “/run/clockboundd/clockboundd.sock”, but if a different desired location has been set up this allows its usage.

If using the default location at “/run/clockboundd/clockboundd.sock”, use new() instead.

§Arguments
  • clock_bound_d_socket - The path at which the clockboundd.sock lives.
§Examples
use clock_bound_c::ClockBoundClient;
let client = match ClockBoundClient::new_with_path(std::path::PathBuf::from("/run/clockboundd/clockboundd.sock")){
    Ok(client) => client,
    Err(e) => {
        println!("Couldn't create client: {}", e);
        return
    }
};
Examples found in repository?
examples/timing.rs (line 17)
12fn main() {
13    let args: Vec<String> = env::args().collect();
14    let clock_bound_d_socket = &args[1];
15
16    let client =
17        match ClockBoundClient::new_with_path(std::path::PathBuf::from(clock_bound_d_socket)) {
18            Ok(client) => client,
19            Err(e) => {
20                println!("Could not create client: {}", e);
21                return;
22            }
23        };
24
25    let (response, _result) = match client.timing(foo()) {
26        Ok((response, result)) => (response, result),
27        Err((e, _res)) => {
28            println!("Could not complete timing request: {}", e);
29            return;
30        }
31    };
32
33    let datetime_earliest: DateTime<Utc> = response.earliest_start.into();
34    let datetime_latest: DateTime<Utc> = response.latest_finish.into();
35    let datetime_str_earliest = datetime_earliest.format("%Y-%m-%d %H:%M:%S.%f").to_string();
36    let datetime_str_latest = datetime_latest.format("%Y-%m-%d %H:%M:%S.%f").to_string();
37
38    println!(
39        "Earliest start time for the timing request: {:?}", datetime_str_earliest
40    );
41    println!(
42        "Latest finish time for the timing request: {:?}", datetime_str_latest
43    );
44    println!(
45        "Minimum execution duration of timing request: {:?}", response.min_execution_time
46    );
47    println!(
48        "Maximum execution duration of timing request: {:?}", response.max_execution_time
49    )
50}
More examples
Hide additional examples
examples/now.rs (line 14)
9fn main() {
10    let args: Vec<String> = env::args().collect();
11    let clock_bound_d_socket = &args[1];
12
13    let client =
14        match ClockBoundClient::new_with_path(std::path::PathBuf::from(clock_bound_d_socket)) {
15            Ok(client) => client,
16            Err(e) => {
17                println!("Could not create client: {}", e);
18                return;
19            }
20        };
21
22    let response = match client.now() {
23        Ok(response) => response,
24        Err(e) => {
25            println!("Could not complete now request: {}", e);
26            return;
27        }
28    };
29
30    let earliest_d = UNIX_EPOCH + Duration::from_nanos(response.bound.earliest);
31    let latest_d = UNIX_EPOCH + Duration::from_nanos(response.bound.latest);
32    let timestamp_d = UNIX_EPOCH + Duration::from_nanos(response.timestamp);
33    let datetime_earliest = DateTime::<Utc>::from(earliest_d);
34    let datetime_latest = DateTime::<Utc>::from(latest_d);
35    let datetime_timestamp = DateTime::<Utc>::from(timestamp_d);
36    let datetime_str_earliest = datetime_earliest.format("%Y-%m-%d %H:%M:%S.%f").to_string();
37    let datetime_str_latest = datetime_latest.format("%Y-%m-%d %H:%M:%S.%f").to_string();
38    let datetime_str_timestamp = datetime_timestamp
39        .format("%Y-%m-%d %H:%M:%S.%f")
40        .to_string();
41
42    println!(
43        "The UTC timestamp {} has the following error bounds.",
44        datetime_str_timestamp
45    );
46    println!(
47        "In nanoseconds since the Unix epoch: ({:?},{:?})",
48        response.bound.earliest, response.bound.latest
49    );
50    println!(
51        "In UTC in date/time format: ({}, {})",
52        datetime_str_earliest, datetime_str_latest
53    );
54}
examples/after.rs (line 16)
11fn main() {
12    let args: Vec<String> = env::args().collect();
13    let clock_bound_d_socket = &args[1];
14
15    let client =
16        match ClockBoundClient::new_with_path(std::path::PathBuf::from(clock_bound_d_socket)) {
17            Ok(client) => client,
18            Err(e) => {
19                println!("Could not create client: {}", e);
20                return;
21            }
22        };
23
24    // Get the current time in nanoseconds since the Unix Epoch
25    let timestamp = Utc::now().timestamp_nanos() as u64;
26
27    // Test with a timestamp 1 second in the future
28    let timestamp = timestamp + ONE_SECOND_IN_NANOSECONDS;
29
30    // Checks if a point in time is after the current time's error bounds
31    let response = match client.after(timestamp) {
32        Ok(response) => response,
33        Err(e) => {
34            println!("Couldn't complete after request: {}", e);
35            return;
36        }
37    };
38
39    // A clock synchronized via NTP should generally not be a second off. One second past the
40    // current time should generally be after the latest error bound and should return true.
41    if response.after == false {
42        println!(
43            "{} nanoseconds since the Unix Epoch is not after the current time's error bounds.",
44            timestamp
45        )
46    } else if response.after == true {
47        println!(
48            "{} nanoseconds since the Unix Epoch is after the current time's error bounds.",
49            timestamp
50        )
51    }
52
53    println!("Waiting 2 seconds...");
54
55    // Checking again after the timestamp has passed should no longer be after the latest error
56    // bound and return false.
57    sleep(Duration::from_secs(2));
58
59    // Checks if a point in time is after the current time's error bounds
60    let response = match client.after(timestamp) {
61        Ok(response) => response,
62        Err(e) => {
63            println!("Couldn't complete after request: {}", e);
64            return;
65        }
66    };
67
68    if response.after == false {
69        println!(
70            "{} nanoseconds since the Unix Epoch is not after the current time's error bounds.",
71            timestamp
72        )
73    } else if response.after == true {
74        println!(
75            "{} nanoseconds since the Unix Epoch is after the current time's error bounds.",
76            timestamp
77        )
78    }
79}
examples/before.rs (line 14)
9fn main() {
10    let args: Vec<String> = env::args().collect();
11    let clock_bound_d_socket = &args[1];
12
13    let client =
14        match ClockBoundClient::new_with_path(std::path::PathBuf::from(clock_bound_d_socket)) {
15            Ok(client) => client,
16            Err(e) => {
17                println!("Could not create client: {}", e);
18                return;
19            }
20        };
21
22    // Get the current time in nanoseconds since the Unix Epoch
23    let timestamp = Utc::now().timestamp_nanos() as u64;
24
25    // Checks if a point in time is before the current time's error bounds
26    let response = match client.before(timestamp) {
27        Ok(response) => response,
28        Err(e) => {
29            println!("Couldn't complete before request: {}", e);
30            return;
31        }
32    };
33
34    // With a before request done using the current time for comparison, it is likely that the
35    // request is processed faster than the local Clock Error Bound. This means that generally the
36    // current time will not be before the earliest bound and therefore return false.
37    if response.before == false {
38        println!(
39            "{} nanoseconds since the Unix Epoch is not before the current time's error bounds.",
40            timestamp
41        )
42    } else if response.before == true {
43        println!(
44            "{} nanoseconds since the Unix Epoch is before the current time's error bounds.",
45            timestamp
46        )
47    }
48
49    println!("Waiting 1 second...");
50
51    // Checking again after a brief period of time (a pessimistic 1 second for this example's sake)
52    // the timestamp should be before the earliest error bound and return true.
53    sleep(Duration::from_secs(1));
54
55    // Checks if a point in time is before the current time's error bounds
56    let response = match client.before(timestamp) {
57        Ok(response) => response,
58        Err(e) => {
59            println!("Couldn't complete before request: {}", e);
60            return;
61        }
62    };
63
64    if response.before == false {
65        println!(
66            "{} nanoseconds since the Unix Epoch is not before the current time's error bounds.",
67            timestamp
68        )
69    } else if response.before == true {
70        println!(
71            "{} nanoseconds since the Unix Epoch is before the current time's error bounds.",
72            timestamp
73        )
74    }
75}
Source

pub fn now(&self) -> Result<ResponseNow, ClockBoundCError>

Returns the bounds of the current system time +/- the error calculated from chrony.

§Examples
use clock_bound_c::ClockBoundClient;
let client = match ClockBoundClient::new(){
    Ok(client) => client,
    Err(e) => {
        println!("Couldn't create client: {}", e);
        return
    }
};
let response = match client.now(){
    Ok(response) => response,
    Err(e) => {
        println!("Couldn't complete now request: {}", e);
        return
    }
};
Examples found in repository?
examples/now.rs (line 22)
9fn main() {
10    let args: Vec<String> = env::args().collect();
11    let clock_bound_d_socket = &args[1];
12
13    let client =
14        match ClockBoundClient::new_with_path(std::path::PathBuf::from(clock_bound_d_socket)) {
15            Ok(client) => client,
16            Err(e) => {
17                println!("Could not create client: {}", e);
18                return;
19            }
20        };
21
22    let response = match client.now() {
23        Ok(response) => response,
24        Err(e) => {
25            println!("Could not complete now request: {}", e);
26            return;
27        }
28    };
29
30    let earliest_d = UNIX_EPOCH + Duration::from_nanos(response.bound.earliest);
31    let latest_d = UNIX_EPOCH + Duration::from_nanos(response.bound.latest);
32    let timestamp_d = UNIX_EPOCH + Duration::from_nanos(response.timestamp);
33    let datetime_earliest = DateTime::<Utc>::from(earliest_d);
34    let datetime_latest = DateTime::<Utc>::from(latest_d);
35    let datetime_timestamp = DateTime::<Utc>::from(timestamp_d);
36    let datetime_str_earliest = datetime_earliest.format("%Y-%m-%d %H:%M:%S.%f").to_string();
37    let datetime_str_latest = datetime_latest.format("%Y-%m-%d %H:%M:%S.%f").to_string();
38    let datetime_str_timestamp = datetime_timestamp
39        .format("%Y-%m-%d %H:%M:%S.%f")
40        .to_string();
41
42    println!(
43        "The UTC timestamp {} has the following error bounds.",
44        datetime_str_timestamp
45    );
46    println!(
47        "In nanoseconds since the Unix epoch: ({:?},{:?})",
48        response.bound.earliest, response.bound.latest
49    );
50    println!(
51        "In UTC in date/time format: ({}, {})",
52        datetime_str_earliest, datetime_str_latest
53    );
54}
Source

pub fn before( &self, before_time: u64, ) -> Result<ResponseBefore, ClockBoundCError>

Returns true if the provided timestamp is before the earliest error bound. Otherwise, returns false.

§Arguments
  • before_time - A timestamp, represented as nanoseconds since the Unix Epoch, that is tested against the earliest error bound.
§Examples
use clock_bound_c::ClockBoundClient;
let client = match ClockBoundClient::new(){
    Ok(client) => client,
    Err(e) => {
        println!("Couldn't create client: {}", e);
        return
    }
};
// Using 0 which equates to the Unix Epoch
let response = match client.before(0){
    Ok(response) => response,
    Err(e) => {
        println!("Couldn't complete before request: {}", e);
        return
    }
};
Examples found in repository?
examples/before.rs (line 26)
9fn main() {
10    let args: Vec<String> = env::args().collect();
11    let clock_bound_d_socket = &args[1];
12
13    let client =
14        match ClockBoundClient::new_with_path(std::path::PathBuf::from(clock_bound_d_socket)) {
15            Ok(client) => client,
16            Err(e) => {
17                println!("Could not create client: {}", e);
18                return;
19            }
20        };
21
22    // Get the current time in nanoseconds since the Unix Epoch
23    let timestamp = Utc::now().timestamp_nanos() as u64;
24
25    // Checks if a point in time is before the current time's error bounds
26    let response = match client.before(timestamp) {
27        Ok(response) => response,
28        Err(e) => {
29            println!("Couldn't complete before request: {}", e);
30            return;
31        }
32    };
33
34    // With a before request done using the current time for comparison, it is likely that the
35    // request is processed faster than the local Clock Error Bound. This means that generally the
36    // current time will not be before the earliest bound and therefore return false.
37    if response.before == false {
38        println!(
39            "{} nanoseconds since the Unix Epoch is not before the current time's error bounds.",
40            timestamp
41        )
42    } else if response.before == true {
43        println!(
44            "{} nanoseconds since the Unix Epoch is before the current time's error bounds.",
45            timestamp
46        )
47    }
48
49    println!("Waiting 1 second...");
50
51    // Checking again after a brief period of time (a pessimistic 1 second for this example's sake)
52    // the timestamp should be before the earliest error bound and return true.
53    sleep(Duration::from_secs(1));
54
55    // Checks if a point in time is before the current time's error bounds
56    let response = match client.before(timestamp) {
57        Ok(response) => response,
58        Err(e) => {
59            println!("Couldn't complete before request: {}", e);
60            return;
61        }
62    };
63
64    if response.before == false {
65        println!(
66            "{} nanoseconds since the Unix Epoch is not before the current time's error bounds.",
67            timestamp
68        )
69    } else if response.before == true {
70        println!(
71            "{} nanoseconds since the Unix Epoch is before the current time's error bounds.",
72            timestamp
73        )
74    }
75}
Source

pub fn after(&self, after_time: u64) -> Result<ResponseAfter, ClockBoundCError>

Returns true if the provided timestamp is after the latest error bound. Otherwise, returns false.

§Arguments
  • after_time - A timestamp, represented as nanoseconds since the Unix Epoch, that is tested against the latest error bound.
§Examples
use clock_bound_c::ClockBoundClient;
let client = match ClockBoundClient::new(){
    Ok(client) => client,
    Err(e) => {
        println!("Couldn't create client: {}", e);
        return
    }
};
// Using 0 which equates to the Unix Epoch
let response = match client.after(0){
    Ok(response) => response,
    Err(e) => {
        println!("Couldn't complete after request: {}", e);
        return
    }
};
Examples found in repository?
examples/after.rs (line 31)
11fn main() {
12    let args: Vec<String> = env::args().collect();
13    let clock_bound_d_socket = &args[1];
14
15    let client =
16        match ClockBoundClient::new_with_path(std::path::PathBuf::from(clock_bound_d_socket)) {
17            Ok(client) => client,
18            Err(e) => {
19                println!("Could not create client: {}", e);
20                return;
21            }
22        };
23
24    // Get the current time in nanoseconds since the Unix Epoch
25    let timestamp = Utc::now().timestamp_nanos() as u64;
26
27    // Test with a timestamp 1 second in the future
28    let timestamp = timestamp + ONE_SECOND_IN_NANOSECONDS;
29
30    // Checks if a point in time is after the current time's error bounds
31    let response = match client.after(timestamp) {
32        Ok(response) => response,
33        Err(e) => {
34            println!("Couldn't complete after request: {}", e);
35            return;
36        }
37    };
38
39    // A clock synchronized via NTP should generally not be a second off. One second past the
40    // current time should generally be after the latest error bound and should return true.
41    if response.after == false {
42        println!(
43            "{} nanoseconds since the Unix Epoch is not after the current time's error bounds.",
44            timestamp
45        )
46    } else if response.after == true {
47        println!(
48            "{} nanoseconds since the Unix Epoch is after the current time's error bounds.",
49            timestamp
50        )
51    }
52
53    println!("Waiting 2 seconds...");
54
55    // Checking again after the timestamp has passed should no longer be after the latest error
56    // bound and return false.
57    sleep(Duration::from_secs(2));
58
59    // Checks if a point in time is after the current time's error bounds
60    let response = match client.after(timestamp) {
61        Ok(response) => response,
62        Err(e) => {
63            println!("Couldn't complete after request: {}", e);
64            return;
65        }
66    };
67
68    if response.after == false {
69        println!(
70            "{} nanoseconds since the Unix Epoch is not after the current time's error bounds.",
71            timestamp
72        )
73    } else if response.after == true {
74        println!(
75            "{} nanoseconds since the Unix Epoch is after the current time's error bounds.",
76            timestamp
77        )
78    }
79}
Source

pub fn timing<A, F>( &self, f: F, ) -> Result<(TimingResult, A), (ClockBoundCError, Result<A, F>)>
where F: FnOnce() -> A,

Execute f and return bounds on execution time

Examples found in repository?
examples/timing.rs (line 25)
12fn main() {
13    let args: Vec<String> = env::args().collect();
14    let clock_bound_d_socket = &args[1];
15
16    let client =
17        match ClockBoundClient::new_with_path(std::path::PathBuf::from(clock_bound_d_socket)) {
18            Ok(client) => client,
19            Err(e) => {
20                println!("Could not create client: {}", e);
21                return;
22            }
23        };
24
25    let (response, _result) = match client.timing(foo()) {
26        Ok((response, result)) => (response, result),
27        Err((e, _res)) => {
28            println!("Could not complete timing request: {}", e);
29            return;
30        }
31    };
32
33    let datetime_earliest: DateTime<Utc> = response.earliest_start.into();
34    let datetime_latest: DateTime<Utc> = response.latest_finish.into();
35    let datetime_str_earliest = datetime_earliest.format("%Y-%m-%d %H:%M:%S.%f").to_string();
36    let datetime_str_latest = datetime_latest.format("%Y-%m-%d %H:%M:%S.%f").to_string();
37
38    println!(
39        "Earliest start time for the timing request: {:?}", datetime_str_earliest
40    );
41    println!(
42        "Latest finish time for the timing request: {:?}", datetime_str_latest
43    );
44    println!(
45        "Minimum execution duration of timing request: {:?}", response.min_execution_time
46    );
47    println!(
48        "Maximum execution duration of timing request: {:?}", response.max_execution_time
49    )
50}

Trait Implementations§

Source§

impl Drop for ClockBoundClient

Source§

fn drop(&mut self)

Remove the client socket file when a ClockBoundClient is dropped.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V