lssa/nssa/core/src/address.rs

99 lines
2.5 KiB
Rust
Raw Normal View History

2025-09-30 15:30:28 -03:00
use serde::{Deserialize, Serialize};
2025-10-02 09:17:19 -03:00
#[cfg(feature = "host")]
use std::{fmt::Display, str::FromStr};
2025-10-23 17:33:25 +03:00
#[cfg(feature = "host")]
use base58::{FromBase58, ToBase58};
2025-10-03 08:08:54 -03:00
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Hash)]
2025-09-30 16:45:25 -03:00
#[cfg_attr(
any(feature = "host", test),
2025-10-03 08:08:54 -03:00
derive(Debug, Copy, PartialOrd, Ord, Default)
2025-09-30 16:45:25 -03:00
)]
2025-09-30 15:30:28 -03:00
pub struct Address {
value: [u8; 32],
}
impl Address {
pub fn new(value: [u8; 32]) -> Self {
Self { value }
}
pub fn value(&self) -> &[u8; 32] {
&self.value
}
}
impl AsRef<[u8]> for Address {
fn as_ref(&self) -> &[u8] {
&self.value
}
}
2025-09-30 16:45:25 -03:00
#[cfg(feature = "host")]
2025-09-30 15:30:28 -03:00
#[derive(Debug, thiserror::Error)]
pub enum AddressError {
2025-10-23 17:33:25 +03:00
#[error("invalid base58")]
InvalidBase58(#[from] anyhow::Error),
2025-09-30 15:30:28 -03:00
#[error("invalid length: expected 32 bytes, got {0}")]
InvalidLength(usize),
}
2025-09-30 16:45:25 -03:00
#[cfg(feature = "host")]
2025-09-30 15:30:28 -03:00
impl FromStr for Address {
type Err = AddressError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
2025-10-23 17:33:25 +03:00
let bytes = s
.from_base58()
.map_err(|err| anyhow::anyhow!("Invalid base58 err {err:?}"))?;
2025-09-30 15:30:28 -03:00
if bytes.len() != 32 {
return Err(AddressError::InvalidLength(bytes.len()));
}
let mut value = [0u8; 32];
value.copy_from_slice(&bytes);
Ok(Address { value })
}
}
2025-09-30 16:45:25 -03:00
#[cfg(feature = "host")]
2025-09-30 15:30:28 -03:00
impl Display for Address {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2025-10-23 17:33:25 +03:00
write!(f, "{}", self.value.to_base58())
2025-09-30 15:30:28 -03:00
}
}
#[cfg(test)]
mod tests {
2025-09-30 16:45:25 -03:00
2025-09-30 15:30:28 -03:00
use super::{Address, AddressError};
#[test]
fn parse_valid_address() {
2025-10-24 11:12:32 +03:00
let base58_str = "11111111111111111111111111111111";
let addr: Address = base58_str.parse().unwrap();
2025-09-30 15:30:28 -03:00
assert_eq!(addr.value, [0u8; 32]);
}
#[test]
2025-10-24 11:12:32 +03:00
fn parse_invalid_base58() {
let base58_str = "00".repeat(32); // invalid base58 chars
let result = base58_str.parse::<Address>().unwrap_err();
2025-10-23 17:33:25 +03:00
assert!(matches!(result, AddressError::InvalidBase58(_)));
2025-09-30 15:30:28 -03:00
}
#[test]
fn parse_wrong_length_short() {
2025-10-24 11:12:32 +03:00
let base58_str = "11".repeat(31); // 62 chars = 31 bytes
let result = base58_str.parse::<Address>().unwrap_err();
2025-09-30 15:30:28 -03:00
assert!(matches!(result, AddressError::InvalidLength(_)));
}
#[test]
fn parse_wrong_length_long() {
2025-10-24 11:12:32 +03:00
let base58_str = "11".repeat(33); // 66 chars = 33 bytes
let result = base58_str.parse::<Address>().unwrap_err();
2025-09-30 15:30:28 -03:00
assert!(matches!(result, AddressError::InvalidLength(_)));
}
}