use crate::actor_error;
use std::any::type_name;
use std::marker::PhantomData;
use crate::tcid_ops;
use super::{TCid, TCidContent};
use anyhow::{anyhow, Result};
use fvm_ipld_amt::Amt;
use fvm_ipld_amt::Error as AmtError;
use fvm_ipld_blockstore::{Blockstore, MemoryBlockstore};
use serde::de::DeserializeOwned;
use serde::ser::Serialize;
const AMT_BIT_WIDTH: u32 = 3;
#[derive(PartialEq, Eq, Clone, Debug)]
pub struct TAmt<V, const W: u32 = AMT_BIT_WIDTH> {
_phantom_v: PhantomData<V>,
}
impl<V, const W: u32> TCidContent for TAmt<V, W> {}
impl<V, const W: u32> TCid<TAmt<V, W>>
where
V: Serialize + DeserializeOwned,
{
pub fn new_amt<S: Blockstore>(store: &S) -> Result<Self> {
let cid = Amt::<V, _>::new_with_bit_width(store, W)
.flush()
.map_err(|e| anyhow!("Failed to create empty array: {}", e))?;
Ok(Self::from(cid))
}
pub fn maybe_load<'s, S: Blockstore>(&self, store: &'s S) -> Result<Option<Amt<V, &'s S>>> {
match Amt::<V, _>::load(&self.cid, store) {
Ok(content) => Ok(Some(content)),
Err(AmtError::CidNotFound(_)) => Ok(None),
Err(other) => Err(anyhow!(other)),
}
}
pub fn flush<'s, S: Blockstore>(&mut self, mut value: Amt<V, &'s S>) -> Result<Amt<V, &'s S>> {
let cid = value
.flush()
.map_err(|e| anyhow!("error flushing {}: {}", type_name::<Self>(), e))?;
self.cid = cid;
Ok(value)
}
}
tcid_ops!(TAmt<V : Serialize + DeserializeOwned, W const: u32> => Amt<V, &'s S>);
impl<V, const W: u32> Default for TCid<TAmt<V, W>>
where
V: Serialize + DeserializeOwned,
{
fn default() -> Self {
Self::new_amt(&MemoryBlockstore::new()).unwrap()
}
}