use crate::chain::chain_information;
use alloc::{string::String, vec::Vec};
use core::iter;
use hashbrown::HashMap;
mod defs;
pub fn encode_chain<'a>(
information: impl Into<chain_information::ValidChainInformationRef<'a>>,
block_number_bytes: usize,
) -> String {
encode_chain_storage(
information,
block_number_bytes,
None::<iter::Empty<(Vec<u8>, Vec<u8>)>>,
)
}
pub fn encode_chain_storage<'a>(
information: impl Into<chain_information::ValidChainInformationRef<'a>>,
block_number_bytes: usize,
finalized_storage: Option<impl Iterator<Item = (impl AsRef<[u8]>, impl AsRef<[u8]>)>>,
) -> String {
let information = information.into();
let decoded = defs::SerializedChainInformation::V1(defs::SerializedChainInformationV1::new(
information.as_ref(),
block_number_bytes,
finalized_storage,
));
serde_json::to_string(&decoded).unwrap()
}
pub fn decode_chain(encoded: &str, block_number_bytes: usize) -> Result<Decoded, CorruptedError> {
let encoded: defs::SerializedChainInformation =
serde_json::from_str(encoded).map_err(|e| CorruptedError(CorruptedErrorInner::Serde(e)))?;
let defs::Decoded {
chain_information,
storage,
} = encoded
.decode(block_number_bytes)
.map_err(|err| CorruptedError(CorruptedErrorInner::Deserialize(err)))?;
let chain_information = chain_information::ValidChainInformation::try_from(chain_information)
.map_err(CorruptedErrorInner::InvalidChain)
.map_err(CorruptedError)?;
Ok(Decoded {
chain_information,
storage,
})
}
pub struct Decoded {
pub chain_information: chain_information::ValidChainInformation,
pub storage: Option<HashMap<Vec<u8>, Vec<u8>, fnv::FnvBuildHasher>>,
}
#[derive(Debug, derive_more::Display, derive_more::Error)]
#[display("{_0}")]
pub struct CorruptedError(CorruptedErrorInner);
#[derive(Debug, derive_more::Display, derive_more::Error)]
enum CorruptedErrorInner {
#[display("{_0}")]
Serde(serde_json::Error),
#[display("{_0}")]
Deserialize(defs::DeserializeError),
#[display("Invalid chain information: {_0}")]
InvalidChain(chain_information::ValidityError),
}