use std::fmt::Write as _;
use std::io::{self, BufRead};
use crate::chain::ChainEvent;
use crate::pack_bridge;
use packr_abi::parse_value;
pub fn format_event(event: &ChainEvent) -> String {
let mut out = String::new();
writeln!(out, "---").unwrap();
writeln!(out, "hash: {}", hex::encode(&event.hash)).unwrap();
match &event.parent_hash {
Some(parent) => writeln!(out, "parent: {}", hex::encode(parent)).unwrap(),
None => writeln!(out, "parent: root").unwrap(),
}
if let Ok(value) = pack_bridge::decode_value(&event.data) {
writeln!(out, "{}", value).unwrap();
} else if !event.data.is_empty() {
writeln!(out, "raw: {} bytes", event.data.len()).unwrap();
}
out
}
pub fn format_chain(events: &[ChainEvent]) -> String {
events.iter().map(format_event).collect::<String>()
}
pub fn parse_events(reader: &mut dyn BufRead) -> io::Result<Vec<ChainEvent>> {
let mut events = Vec::new();
let mut hash = String::new();
let mut parent = String::new();
let mut in_event = false;
let mut expecting_value = false;
for line in reader.lines() {
let line = line?;
if line == "---" {
hash.clear();
parent.clear();
in_event = true;
expecting_value = false;
continue;
}
if !in_event {
continue;
}
if let Some(h) = line.strip_prefix("hash: ") {
hash = h.to_string();
expecting_value = false;
} else if let Some(p) = line.strip_prefix("parent: ") {
parent = p.to_string();
expecting_value = true; } else if expecting_value && !line.is_empty() {
let hash_bytes = hex::decode(&hash).unwrap_or_default();
let parent_bytes = if parent == "root" {
None
} else {
Some(hex::decode(&parent).unwrap_or_default())
};
let data = if line.starts_with("raw:") {
vec![] } else {
match parse_value(&line) {
Ok(value) => packr_abi::encode(&value).unwrap_or_default(),
Err(_) => vec![],
}
};
events.push(ChainEvent {
hash: hash_bytes,
parent_hash: parent_bytes,
event_type: String::new(), data,
});
in_event = false;
expecting_value = false;
}
}
Ok(events)
}
pub fn load_chain_file(path: &std::path::Path) -> io::Result<Vec<ChainEvent>> {
let file = std::fs::File::open(path)?;
let mut reader = io::BufReader::new(file);
parse_events(&mut reader)
}