use super::Arc;
use crate::HashOutput;
use anyhow::Result;
use bytes::Bytes;
use cid::Cid;
use futures::{AsyncRead, AsyncReadExt};
use parking_lot::Mutex;
use rand_core::CryptoRngCore;
use serde::{Deserialize, Serialize, Serializer};
use std::collections::HashMap;
pub fn error<T>(err: impl std::error::Error + Send + Sync + 'static) -> Result<T> {
Err(err.into())
}
pub async fn read_fully(
stream: &mut (impl AsyncRead + Unpin),
buffer: &mut [u8],
) -> Result<(usize, bool)> {
let mut bytes_read = 0;
let mut done = false;
loop {
let bytes_read_in_iteration = stream.read(&mut buffer[bytes_read..]).await?;
bytes_read += bytes_read_in_iteration;
if bytes_read_in_iteration == 0 {
done = true;
break;
}
if bytes_read == buffer.len() {
break;
}
}
Ok((bytes_read, done))
}
pub fn get_random_bytes<const N: usize>(rng: &mut impl CryptoRngCore) -> [u8; N] {
let mut bytes = [0u8; N];
rng.fill_bytes(&mut bytes);
bytes
}
pub fn to_hash_output(bytes: &[u8]) -> HashOutput {
let mut nibbles = [0u8; 32];
nibbles[..bytes.len()].copy_from_slice(bytes);
nibbles
}
pub(crate) fn serialize_cid_map<S>(
map: &Arc<Mutex<HashMap<Cid, Bytes>>>,
serializer: S,
) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let map = map
.lock()
.iter()
.map(|(cid, bytes)| (cid.to_string(), bytes.to_vec()))
.collect::<HashMap<_, _>>();
map.serialize(serializer)
}
pub(crate) fn deserialize_cid_map<'de, D>(
deserializer: D,
) -> Result<Arc<Mutex<HashMap<Cid, Bytes>>>, D::Error>
where
D: serde::Deserializer<'de>,
{
let map = HashMap::<String, Vec<u8>>::deserialize(deserializer)?;
let map = map
.into_iter()
.map(|(cid, bytes)| {
let cid = cid.parse::<Cid>().map_err(serde::de::Error::custom)?;
Ok((cid, bytes.into()))
})
.collect::<Result<_, _>>()?;
Ok(Arc::new(Mutex::new(map)))
}