use std::fmt::{
self,
Write
};
use std::io::Write as IoWrite;
use std::time::{
Duration,
SystemTime
};
use bincode::{
config,
error::DecodeError,
error::EncodeError
};
use bincode::serde::{
decode_from_slice,
encode_into_std_write,
encode_to_vec
};
use conciliator::Buffer;
use serde::{Serialize, Deserialize, de::DeserializeOwned};
use tokio::time::{
timeout,
Timeout
};
use crate::peer::NodeID;
pub mod tree {
pub const ROOT: &str = "┬";
pub const STEM: &str = "│ ";
pub const KNOT: &str = "├─";
pub const TAIL: &str = "└─";
}
pub type Task = tokio::task::JoinHandle<()>;
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
pub struct PeerInfo {
pub id: NodeID,
pub name: String
}
impl PeerInfo {
pub fn create(name: String) -> Self {
Self {
id: NodeID::random(),
name
}
}
}
pub fn fmt_bytes(arr: &[u8]) -> String {
let mut text = String::new();
for b in arr {
write!(text, "{b:02X}").expect("Formatting bytes failed!");
}
text
}
pub fn fmt_time(f: &mut fmt::Formatter<'_>, time: SystemTime) -> fmt::Result {
match time.elapsed() {
Ok(elapsed) => write!(f, "{elapsed:.2?} ago"),
Err(future) => write!(f, "in {:.2?}", future.duration())
}
}
pub fn push_time(buf: &mut Buffer, time: SystemTime) {
match time.elapsed() {
Ok(elapsed) => buf.push(format_args!("{elapsed:.2?} ago")),
Err(future) => buf.push(format_args!("in {:.2?}", future.duration()))
};
}
pub trait TimeoutFuture: Sized + futures::Future {
fn timeout(self, duration: Duration) -> Timeout<Self> {
timeout(duration, self)
}
fn timeout_ms(self, ms: u64) -> Timeout<Self> {
timeout(Duration::from_millis(ms), self)
}
}
impl<Fut: futures::Future> TimeoutFuture for Fut {}
#[doc(hidden)]
pub trait NeverFn {type Output;}
impl<T> NeverFn for fn() -> T {type Output = T;}
pub type Never = <fn()-> ! as NeverFn>::Output;
pub(crate) trait OptTimeExt {
fn set_now(&mut self);
}
impl OptTimeExt for Option<SystemTime> {
fn set_now(&mut self) {
self.replace(SystemTime::now());
}
}
pub fn bincode_serialize<T: Serialize>(thing: T)
-> Result<Vec<u8>, EncodeError>
{
encode_to_vec(thing, config::legacy())
}
pub fn bincode_serialize_into<T: Serialize, W: IoWrite>(dst: &mut W, thing: T)
-> Result<usize, EncodeError>
{
encode_into_std_write(thing, dst, config::legacy())
}
pub fn bincode_deserialize<T: DeserializeOwned>(buf: &[u8])
-> Result<T, DecodeError>
{
decode_from_slice(buf, config::legacy())
.map(|(t, _len)| t)
}