use crate::errors::AddressError;
use alloy::primitives::Address;
use std::str::FromStr;
#[must_use]
pub fn address_to_checksum_string(address: &Address) -> String {
address.to_checksum(None)
}
pub fn to_checksum_address_str(addr_str: &str) -> Result<String, AddressError> {
let addr = parse_address(addr_str)?;
Ok(address_to_checksum_string(&addr))
}
pub fn parse_address(s: &str) -> Result<Address, AddressError> {
Address::from_str(s).map_err(|e| AddressError::InvalidAddress(e.to_string()))
}
pub fn to_checksum_address_bytes(bytes: &[u8]) -> Result<String, AddressError> {
if bytes.len() != 20 {
return Err(AddressError::InvalidByteLength(bytes.len()));
}
let address = Address::from_slice(bytes);
Ok(address_to_checksum_string(&address))
}
#[cfg(test)]
#[expect(clippy::expect_used)]
mod tests {
use super::*;
#[test]
fn test_checksum_from_str() {
let result = to_checksum_address_str("0x66f9664f97f2b50f62d13ea064982f936de76657");
assert!(result.is_ok());
let checksummed = result.expect("valid address should checksum successfully");
assert!(checksummed.contains(|c: char| c.is_ascii_uppercase()));
assert!(checksummed.contains(|c: char| c.is_ascii_lowercase()));
}
#[test]
fn test_checksum_from_str_invalid() {
let result = to_checksum_address_str("not-an-address");
assert!(matches!(result, Err(AddressError::InvalidAddress(_))));
}
#[test]
fn test_checksum_from_bytes() {
let bytes: [u8; 20] = [
0x66, 0xf9, 0x66, 0x4f, 0x97, 0xf2, 0xb5, 0x0f, 0x62, 0xd1, 0x3e, 0xa0, 0x64, 0x98,
0x2f, 0x93, 0x6d, 0xe7, 0x66, 0x57,
];
let result = to_checksum_address_bytes(&bytes);
assert!(result.is_ok());
}
#[test]
fn test_checksum_from_bytes_wrong_length() {
let bytes: [u8; 10] = [0x66; 10];
let result = to_checksum_address_bytes(&bytes);
assert!(matches!(result, Err(AddressError::InvalidByteLength(10))));
}
#[test]
fn test_parse_address_valid() {
let result = parse_address("0x66f9664f97f2b50f62d13ea064982f936de76657");
assert!(result.is_ok());
}
#[test]
fn test_parse_address_invalid() {
let result = parse_address("not-an-address");
assert!(matches!(result, Err(AddressError::InvalidAddress(_))));
}
}