use std::collections::HashMap;
use crate::error::{InternalError, InvalidStateError};
use crate::state::{Reader, StateError, ValueIter, ValueIterResult};
use crate::state::merkle::kv::{error::StateDatabaseError, MerkleRadixTree, MerkleState};
impl Reader for MerkleState {
type Filter = str;
fn get(
&self,
state_id: &Self::StateId,
keys: &[Self::Key],
) -> Result<HashMap<Self::Key, Self::Value>, StateError> {
let merkle_tree =
MerkleRadixTree::new(self.db.clone(), Some(state_id)).map_err(|err| match err {
StateDatabaseError::NotFound(msg) => {
StateError::from(InvalidStateError::with_message(msg))
}
_ => StateError::from(InternalError::from_source(Box::new(err))),
})?;
keys.iter().try_fold(HashMap::new(), |mut result, key| {
let value = match merkle_tree.get_by_address(key) {
Ok(value) => value.value,
Err(err) => match err {
StateDatabaseError::NotFound(_) => None,
_ => return Err(InternalError::from_source(Box::new(err)).into()),
},
};
if let Some(value) = value {
result.insert(key.to_string(), value);
}
Ok(result)
})
}
fn filter_iter(
&self,
state_id: &Self::StateId,
filter: Option<&Self::Filter>,
) -> ValueIterResult<ValueIter<(Self::Key, Self::Value)>> {
let merkle_tree =
MerkleRadixTree::new(self.db.clone(), Some(state_id)).map_err(|err| match err {
StateDatabaseError::NotFound(msg) => {
StateError::from(InvalidStateError::with_message(msg))
}
_ => StateError::from(InternalError::from_source(Box::new(err))),
})?;
merkle_tree
.leaves(filter)
.map(|iter| {
Box::new(iter.map(|item| {
item.map_err(|e| StateError::from(InternalError::from_source(Box::new(e))))
})) as Box<dyn Iterator<Item = _>>
})
.map_err(|e| match e {
StateDatabaseError::NotFound(msg) => {
StateError::from(InvalidStateError::with_message(msg))
}
_ => StateError::from(InternalError::from_source(Box::new(e))),
})
}
}