use crate::memory_resolver::resolver::{MemoryAddress, ParseError, PointerSize};
pub struct MemoryAddressBuilder {
address_str: Option<String>,
pointer_size: Option<PointerSize>,
}
impl MemoryAddressBuilder {
pub fn new() -> Self {
Self {
address_str: None,
pointer_size: None,
}
}
pub fn address(mut self, input: &str) -> Self {
self.address_str = Some(input.to_string());
self
}
pub fn x86(mut self) -> Self {
self.pointer_size = Some(PointerSize::Bits32);
self
}
pub fn x64(mut self) -> Self {
self.pointer_size = Some(PointerSize::Bits64);
self
}
pub fn build(self) -> Result<MemoryAddress, ParseError> {
let address_str = self
.address_str
.expect("MemoryAddressBuilder: address() must be called before build()");
let mut addr = MemoryAddress::parse(&address_str)?;
if let Some(size) = self.pointer_size {
addr.pointer_size = size;
}
Ok(addr)
}
}
impl Default for MemoryAddressBuilder {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_builder_basic用法() {
let addr = MemoryAddressBuilder::new()
.address("0x12345678")
.build()
.unwrap();
assert!(matches!(
addr.base,
crate::memory_resolver::resolver::AddressBase::Absolute(_)
));
}
#[test]
fn test_builder_x86_shortcut() {
let addr = MemoryAddressBuilder::new()
.address("app.exe+58C94->308")
.x86()
.build()
.unwrap();
assert_eq!(addr.pointer_size, PointerSize::Bits32);
}
#[test]
fn test_builder_x64_shortcut() {
let addr = MemoryAddressBuilder::new()
.address("game.exe+1000->20")
.x64()
.build()
.unwrap();
assert_eq!(addr.pointer_size, PointerSize::Bits64);
}
#[test]
#[should_panic(expected = "address() must be called before build()")]
fn test_builder_without_address_panics() {
let _addr = MemoryAddressBuilder::new().build().unwrap();
}
#[test]
fn test_builder_invalid_address() {
let result = MemoryAddressBuilder::new()
.address("invalid address string")
.build();
assert!(result.is_err());
}
#[test]
fn test_builder_default_pointer_size() {
let addr = MemoryAddressBuilder::new()
.address("test.exe+100")
.build()
.unwrap();
#[cfg(target_pointer_width = "64")]
assert_eq!(addr.pointer_size, PointerSize::Bits64);
#[cfg(target_pointer_width = "32")]
assert_eq!(addr.pointer_size, PointerSize::Bits32);
}
}