use crate::actor_error;
use std::any::type_name;
use std::marker::PhantomData;
use super::{CodeType, TCid, TCidContent};
use crate::tcid_ops;
use anyhow::Result;
use fvm_ipld_blockstore::Blockstore;
use fvm_ipld_encoding::CborStore;
use serde::de::DeserializeOwned;
use serde::ser::Serialize;
use std::ops::{Deref, DerefMut};
#[derive(PartialEq, Eq, Clone, Debug)]
pub struct TLink<T> {
_phantom_t: PhantomData<T>,
}
impl<T> TCidContent for TLink<T> {}
pub struct StoreContent<'s, S: Blockstore, T> {
store: &'s S,
content: T,
}
impl<'s, S: 's + Blockstore, T> Deref for StoreContent<'s, S, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.content
}
}
impl<'s, S: 's + Blockstore, T> DerefMut for StoreContent<'s, S, T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.content
}
}
impl<T, C: CodeType> TCid<TLink<T>, C>
where
T: Serialize + DeserializeOwned,
{
pub fn new_link<S: Blockstore>(store: &S, value: &T) -> Result<Self> {
let cid = store.put_cbor(value, C::code())?;
Ok(Self::from(cid))
}
pub fn maybe_load<'s, S: Blockstore>(
&self,
store: &'s S,
) -> Result<Option<StoreContent<'s, S, T>>> {
Ok(store
.get_cbor(&self.cid)?
.map(|content| StoreContent { store, content }))
}
pub fn flush<'s, S: Blockstore>(
&mut self,
value: StoreContent<'s, S, T>,
) -> Result<StoreContent<'s, S, T>> {
let cid = value.store.put_cbor(&value.content, C::code())?;
self.cid = cid;
Ok(value)
}
}
tcid_ops!(TLink<T : Serialize + DeserializeOwned>, C: CodeType => StoreContent<'s, S, T>);
impl<T, C: CodeType> Default for TCid<TLink<T>, C> {
fn default() -> Self {
Self::from(cid::Cid::default())
}
}