Skip to main content

mega_evme/common/
hex.rs

1//! Hex loading utilities for mega-evme
2
3use std::{fs, io::Read};
4
5use alloy_primitives::{hex, Bytes};
6
7use super::{EvmeError, Result};
8
9/// Load hex-encoded bytes from an argument or a file. If the file is a dash (-), read from stdin.
10/// Priority: arg > file. Returns `None` if neither is provided.
11pub fn load_hex(arg: Option<String>, file: Option<String>) -> Result<Option<Bytes>> {
12    let hex_string = if let Some(arg) = arg {
13        arg
14    } else if let Some(file) = file {
15        if file == "-" {
16            let mut buffer = String::new();
17            std::io::stdin().read_to_string(&mut buffer)?;
18            buffer
19        } else {
20            fs::read_to_string(file)?
21        }
22    } else {
23        return Ok(None);
24    };
25
26    decode_hex(&hex_string).map(|bytes| Some(Bytes::from(bytes)))
27}
28
29/// Decode hex string, handling optional 0x prefix
30fn decode_hex(s: &str) -> Result<Vec<u8>> {
31    let s = s.trim();
32
33    if s.is_empty() {
34        return Ok(Vec::new());
35    }
36
37    let hex_str = if s.starts_with("0x") || s.starts_with("0X") { &s[2..] } else { s };
38
39    if hex_str.len() % 2 != 0 {
40        return Err(EvmeError::InvalidInput(format!(
41            "Invalid hex string length: {} (must be even)",
42            hex_str.len()
43        )));
44    }
45
46    Ok(hex::decode(hex_str)?)
47}