use std::rc::Rc;
use crate::BlockStore;
use anyhow::Result;
use async_trait::async_trait;
use libipld::{error::SerdeError, serde as ipld_serde, Ipld};
use serde::Serialize;
use serde::Serializer;
macro_rules! impl_async_serialize {
( $( $ty:ty $( : < $( $generics:ident ),+ > )? ),+ ) => {
$(
#[async_trait(?Send)]
impl $( < $( $generics ),+ > )? AsyncSerialize for $ty $( where $( $generics: Serialize ),+ )? {
async fn async_serialize<S: Serializer, BS: BlockStore + ?Sized>(
&self,
serializer: S,
_: &mut BS,
) -> Result<S::Ok, S::Error> {
self.serialize(serializer)
}
}
)+
};
}
pub trait Id {
fn get_id(&self) -> String;
}
#[async_trait(?Send)]
pub trait IpldEq {
async fn eq<B: BlockStore>(&self, other: &Self, store: &mut B) -> Result<bool>;
}
#[async_trait(?Send)]
pub trait AsyncSerialize {
async fn async_serialize<S: Serializer, B: BlockStore + ?Sized>(
&self,
serializer: S,
store: &mut B,
) -> Result<S::Ok, S::Error>;
async fn async_serialize_ipld<B: BlockStore + ?Sized>(
&self,
store: &mut B,
) -> Result<Ipld, SerdeError> {
self.async_serialize(ipld_serde::Serializer, store).await
}
}
#[async_trait(?Send)]
impl<T: AsyncSerialize> AsyncSerialize for Rc<T> {
async fn async_serialize<S: Serializer, B: BlockStore + ?Sized>(
&self,
serializer: S,
store: &mut B,
) -> Result<S::Ok, S::Error> {
self.as_ref().async_serialize(serializer, store).await
}
}
impl_async_serialize! { usize, u128, u64, u32, u16, u8, isize, i128, i64, i32, i16, i8 }
impl_async_serialize! { String, &str }
impl_async_serialize! {
(A,): <A>,
(A, B): <A, B>,
(A, B, C): <A, B, C>,
(A, B, C, D): <A, B, C, D>,
(A, B, C, D, E): <A, B, C, D, E>,
(A, B, C, D, E, F): <A, B, C, D, E, F>,
(A, B, C, D, E, F, G): <A, B, C, D, E, F, G>,
(A, B, C, D, E, F, G, H): <A, B, C, D, E, F, G, H>,
(A, B, C, D, E, F, G, H, I): <A, B, C, D, E, F, G, H, I>,
(A, B, C, D, E, F, G, H, I, J): <A, B, C, D, E, F, G, H, I, J>,
(A, B, C, D, E, F, G, H, I, J, K): <A, B, C, D, E, F, G, H, I, J, K>
}