1use std::{
10 path::PathBuf,
11 time::{Duration, Instant},
12};
13
14use anyhow::Result;
15use bytes::Bytes;
16
17#[allow(clippy::unnecessary_wraps)]
23pub fn to_path_buf(path: &String) -> Result<PathBuf> {
24 Ok(PathBuf::from(path))
25}
26
27#[must_use]
29pub fn send_ts_ping(origin: Instant) -> [u8; 12] {
30 let ts = Instant::now().duration_since(origin);
31 let (ts1, ts2) = (ts.as_secs(), ts.subsec_nanos());
32 let mut ts = [0; 12];
33 ts[0..8].copy_from_slice(&ts1.to_be_bytes());
34 ts[8..12].copy_from_slice(&ts2.to_be_bytes());
35 ts
36}
37
38pub fn parse_ts_ping(bytes: &Bytes) -> Option<Duration> {
40 if bytes.len() == 12 {
41 let secs_bytes = <[u8; 8]>::try_from(&bytes[0..8]).unwrap_or([0; 8]);
42 let nanos_bytes = <[u8; 4]>::try_from(&bytes[8..12]).unwrap_or([0; 4]);
43 let secs = u64::from_be_bytes(secs_bytes);
44 let nanos = u32::from_be_bytes(nanos_bytes);
45 Some(Duration::new(secs, nanos))
46 } else {
47 None
48 }
49}
50
51#[allow(clippy::mut_mut)]
52pub(crate) fn until_err<T>(err: &mut &mut Result<()>, item: Result<T>) -> Option<T> {
53 match item {
54 Ok(item) => Some(item),
55 Err(e) => {
56 **err = Err(e);
57 None
58 }
59 }
60}
61
62pub(crate) fn as_two_digit(values: &[u8]) -> String {
63 let two_digit_values = values
64 .iter()
65 .map(|s| format!("{s:02}"))
66 .collect::<Vec<String>>();
67 two_digit_values.join(",")
68}