pub use self::types::{Height, Round, ValidatorId};
pub use self::user_agent::{exonum_version, os_info, rust_version, user_agent};
pub(crate) use self::ordered_map::OrderedMap;
pub use self::types::Milliseconds;
mod ordered_map;
use env_logger::Builder;
use log::SetLoggerError;
mod types;
mod user_agent;
pub fn init_logger() -> Result<(), SetLoggerError> {
Builder::from_default_env()
.format_timestamp_nanos()
.try_init()
}
pub trait ValidateInput: Sized {
type Error;
fn validate(&self) -> Result<(), Self::Error>;
fn into_validated(self) -> Result<Self, Self::Error> {
self.validate().map(|_| self)
}
}
pub fn byzantine_quorum(total: usize) -> usize {
total * 2 / 3 + 1
}
pub mod pb_optional_hash {
use exonum_crypto::{proto::types::Hash as PbHash, Hash};
use exonum_proto::ProtobufConvert;
pub fn from_pb(pb: PbHash) -> anyhow::Result<Option<Hash>> {
if pb.get_data().is_empty() {
Ok(None)
} else {
Hash::from_pb(pb).map(Some)
}
}
pub fn to_pb(value: &Option<Hash>) -> PbHash {
if let Some(hash) = value {
hash.to_pb()
} else {
PbHash::new()
}
}
}
pub mod pb_version {
use semver::Version;
#[allow(clippy::needless_pass_by_value)] pub fn from_pb(pb: String) -> anyhow::Result<Version> {
pb.parse().map_err(From::from)
}
pub fn to_pb(value: &Version) -> String {
value.to_string()
}
}