use crate::protocols::{BlockExtraInfo, BlockMmObjectInfo};
use super::types::ExtraKeyItem;
pub fn parse_mm_hash_from_extra_key(s: &str) -> Option<u64> {
if s.len() == 64 && s.chars().all(|c| c.is_ascii_hexdigit()) {
return u64::from_str_radix(&s[..16], 16).ok();
}
None
}
pub fn extra_keys_to_block_mm_infos(
extra_keys: Option<Vec<Option<Vec<ExtraKeyItem>>>>,
) -> Option<Vec<Option<BlockExtraInfo>>> {
let extra_keys = extra_keys?;
if extra_keys.is_empty() {
return None;
}
let infos: Vec<Option<BlockExtraInfo>> = extra_keys
.into_iter()
.map(|block_keys| {
let mm_objects: Vec<BlockMmObjectInfo> = block_keys
.unwrap_or_default()
.iter()
.filter_map(|key| match key {
ExtraKeyItem::Hash(hash)
| ExtraKeyItem::HashWithSignedOffset((hash, _))
| ExtraKeyItem::HashWithUnsignedOffset((hash, _)) => {
parse_mm_hash_from_extra_key(hash)
}
ExtraKeyItem::Bytes(_)
| ExtraKeyItem::Signed(_)
| ExtraKeyItem::Unsigned(_)
| ExtraKeyItem::Float(_)
| ExtraKeyItem::Bool(_) => None,
})
.map(|mm_hash| BlockMmObjectInfo {
mm_hash,
offsets: vec![],
})
.collect();
if mm_objects.is_empty() {
None
} else {
Some(BlockExtraInfo { mm_objects })
}
})
.collect();
if infos.iter().all(|i| i.is_none()) {
return None;
}
Some(infos)
}