use std::collections::BTreeMap;
use std::fmt;
use std::sync::Arc;
use crate::store::NodeStore;
use crate::tree::{Hash, Node};
use super::BrowserSourceError;
#[derive(Debug, Clone, PartialEq, Eq)]
pub(super) struct BrowserNodeError(pub(super) BrowserSourceError);
impl fmt::Display for BrowserNodeError {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0.fmt(formatter)
}
}
impl std::error::Error for BrowserNodeError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
Some(&self.0)
}
}
#[derive(Debug, Default)]
pub(super) struct BrowserNodeStore {
nodes: BTreeMap<Hash, Vec<u8>>,
}
impl BrowserNodeStore {
pub(super) fn from_serialized(
nodes: BTreeMap<Hash, Vec<u8>>,
) -> Result<Self, BrowserNodeError> {
for (hash, bytes) in &nodes {
let node = Node::deserialise(bytes)
.map_err(|error| BrowserNodeError(BrowserSourceError::Node { error }))?;
if node.hash() != *hash {
return Err(BrowserNodeError(BrowserSourceError::NodeHashMismatch {
expected: *hash,
actual: node.hash(),
}));
}
}
Ok(Self { nodes })
}
pub(super) const fn serialized(&self) -> &BTreeMap<Hash, Vec<u8>> {
&self.nodes
}
}
impl NodeStore for BrowserNodeStore {
type Error = BrowserNodeError;
fn get(&self, hash: &Hash) -> Result<Option<Arc<Node>>, Self::Error> {
self.nodes
.get(hash)
.map(|bytes| Node::deserialise(bytes).map(Arc::new))
.transpose()
.map_err(|error| BrowserNodeError(BrowserSourceError::Node { error }))
}
fn put(&mut self, node: &Node) -> Result<Hash, Self::Error> {
let hash = node.hash();
self.nodes.insert(hash, node.serialise());
Ok(hash)
}
}