use crate::{
cilassembly::{ChangeRefRc, CilAssembly},
metadata::{
tables::{AssemblyProcessorRaw, TableDataOwned, TableId},
token::Token,
},
Error, Result,
};
#[derive(Debug, Clone)]
pub struct AssemblyProcessorBuilder {
processor: Option<u32>,
}
impl AssemblyProcessorBuilder {
#[must_use]
pub fn new() -> Self {
Self { processor: None }
}
#[must_use]
pub fn processor(mut self, processor: u32) -> Self {
self.processor = Some(processor);
self
}
pub fn build(self, assembly: &mut CilAssembly) -> Result<ChangeRefRc> {
let processor = self.processor.ok_or_else(|| {
Error::ModificationInvalid(
"Processor architecture identifier is required for AssemblyProcessor".to_string(),
)
})?;
let assembly_processor = AssemblyProcessorRaw {
rid: 0,
token: Token::new(0),
offset: 0,
processor,
};
assembly.table_row_add(
TableId::AssemblyProcessor,
TableDataOwned::AssemblyProcessor(assembly_processor),
)
}
}
impl Default for AssemblyProcessorBuilder {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{
cilassembly::ChangeRefKind, test::factories::table::assemblyref::get_test_assembly,
};
#[test]
fn test_assemblyprocessor_builder_new() {
let builder = AssemblyProcessorBuilder::new();
assert!(builder.processor.is_none());
}
#[test]
fn test_assemblyprocessor_builder_default() {
let builder = AssemblyProcessorBuilder::default();
assert!(builder.processor.is_none());
}
#[test]
fn test_assemblyprocessor_builder_x86() -> Result<()> {
let mut assembly = get_test_assembly()?;
let ref_ = AssemblyProcessorBuilder::new()
.processor(0x014C) .build(&mut assembly)
.expect("Should build successfully");
assert_eq!(
ref_.kind(),
ChangeRefKind::TableRow(TableId::AssemblyProcessor)
);
Ok(())
}
#[test]
fn test_assemblyprocessor_builder_x64() -> Result<()> {
let mut assembly = get_test_assembly()?;
let ref_ = AssemblyProcessorBuilder::new()
.processor(0x8664) .build(&mut assembly)
.expect("Should build successfully");
assert_eq!(
ref_.kind(),
ChangeRefKind::TableRow(TableId::AssemblyProcessor)
);
Ok(())
}
#[test]
fn test_assemblyprocessor_builder_ia64() -> Result<()> {
let mut assembly = get_test_assembly()?;
let ref_ = AssemblyProcessorBuilder::new()
.processor(0x0200) .build(&mut assembly)
.expect("Should build successfully");
assert_eq!(
ref_.kind(),
ChangeRefKind::TableRow(TableId::AssemblyProcessor)
);
Ok(())
}
#[test]
fn test_assemblyprocessor_builder_custom() -> Result<()> {
let mut assembly = get_test_assembly()?;
let ref_ = AssemblyProcessorBuilder::new()
.processor(0x1234) .build(&mut assembly)
.expect("Should build successfully");
assert_eq!(
ref_.kind(),
ChangeRefKind::TableRow(TableId::AssemblyProcessor)
);
Ok(())
}
#[test]
fn test_assemblyprocessor_builder_missing_processor() -> Result<()> {
let mut assembly = get_test_assembly()?;
let result = AssemblyProcessorBuilder::new().build(&mut assembly);
assert!(result.is_err());
match result.unwrap_err() {
Error::ModificationInvalid(details) => {
assert!(details.contains("Processor architecture identifier is required"));
}
_ => panic!("Expected ModificationInvalid error"),
}
Ok(())
}
#[test]
fn test_assemblyprocessor_builder_clone() {
let builder = AssemblyProcessorBuilder::new().processor(0x014C);
let cloned = builder.clone();
assert_eq!(builder.processor, cloned.processor);
}
#[test]
fn test_assemblyprocessor_builder_debug() {
let builder = AssemblyProcessorBuilder::new().processor(0x8664);
let debug_str = format!("{builder:?}");
assert!(debug_str.contains("AssemblyProcessorBuilder"));
assert!(debug_str.contains("processor"));
}
#[test]
fn test_assemblyprocessor_builder_fluent_interface() -> Result<()> {
let mut assembly = get_test_assembly()?;
let ref_ = AssemblyProcessorBuilder::new()
.processor(0x9999)
.build(&mut assembly)
.expect("Should build successfully");
assert_eq!(
ref_.kind(),
ChangeRefKind::TableRow(TableId::AssemblyProcessor)
);
Ok(())
}
#[test]
fn test_assemblyprocessor_builder_multiple_builds() -> Result<()> {
let mut assembly = get_test_assembly()?;
let ref1 = AssemblyProcessorBuilder::new()
.processor(0x014C) .build(&mut assembly)
.expect("Should build first processor");
let ref2 = AssemblyProcessorBuilder::new()
.processor(0x8664) .build(&mut assembly)
.expect("Should build second processor");
assert!(!std::sync::Arc::ptr_eq(&ref1, &ref2));
assert_eq!(
ref1.kind(),
ChangeRefKind::TableRow(TableId::AssemblyProcessor)
);
assert_eq!(
ref2.kind(),
ChangeRefKind::TableRow(TableId::AssemblyProcessor)
);
Ok(())
}
#[test]
fn test_assemblyprocessor_builder_zero_processor() -> Result<()> {
let mut assembly = get_test_assembly()?;
let ref_ = AssemblyProcessorBuilder::new()
.processor(0) .build(&mut assembly)
.expect("Should build successfully");
assert_eq!(
ref_.kind(),
ChangeRefKind::TableRow(TableId::AssemblyProcessor)
);
Ok(())
}
#[test]
fn test_assemblyprocessor_builder_max_processor() -> Result<()> {
let mut assembly = get_test_assembly()?;
let ref_ = AssemblyProcessorBuilder::new()
.processor(u32::MAX) .build(&mut assembly)
.expect("Should build successfully");
assert_eq!(
ref_.kind(),
ChangeRefKind::TableRow(TableId::AssemblyProcessor)
);
Ok(())
}
}