use std::str::FromStr;
use alloy_primitives::Address;
pub fn validate_address(address: &str) -> anyhow::Result<Address> {
if !address.starts_with("0x") {
anyhow::bail!("Ethereum address must start with '0x': {address}");
}
let parsed_address = Address::from_str(address)
.map_err(|e| anyhow::anyhow!("Blockchain address '{address}' is incorrect: {e}"))?;
Address::parse_checksummed(address, None)
.map_err(|_| anyhow::anyhow!("Blockchain address '{address}' has incorrect checksum"))?;
Ok(parsed_address)
}
#[cfg(test)]
mod tests {
use rstest::rstest;
use super::*;
#[rstest]
fn test_validate_address_invalid_prefix() {
let invalid_address = "742d35Cc6634C0532925a3b844Bc454e4438f44e";
let result = validate_address(invalid_address);
assert!(result.is_err());
assert_eq!(
result.unwrap_err().to_string(),
"Ethereum address must start with '0x': 742d35Cc6634C0532925a3b844Bc454e4438f44e"
);
}
#[rstest]
fn test_validate_invalid_address_format() {
let invalid_length_address = "0x1233";
let invalid_characters_address = "0xZZZd35Cc6634C0532925a3b844Bc454e4438f44e";
assert_eq!(
validate_address(invalid_length_address)
.unwrap_err()
.to_string(),
"Blockchain address '0x1233' is incorrect: invalid string length"
);
assert_eq!(
validate_address(invalid_characters_address)
.unwrap_err()
.to_string(),
"Blockchain address '0xZZZd35Cc6634C0532925a3b844Bc454e4438f44e' is incorrect: invalid character 'Z' at position 0"
);
}
#[rstest]
fn test_validate_invalid_checksum() {
let invalid_checksum_address = "0x742d35cc6634c0532925a3b844bc454e4438f44e";
assert_eq!(
validate_address(invalid_checksum_address)
.unwrap_err()
.to_string(),
"Blockchain address '0x742d35cc6634c0532925a3b844bc454e4438f44e' has incorrect checksum"
);
}
}