use crate::{
cilassembly::{ChangeRefRc, CilAssembly},
metadata::{
tables::{EncMapRaw, TableDataOwned, TableId},
token::Token,
},
Error, Result,
};
#[derive(Debug, Clone)]
pub struct EncMapBuilder {
original_token: Option<u32>,
}
impl EncMapBuilder {
#[must_use]
pub fn new() -> Self {
Self {
original_token: None,
}
}
#[must_use]
pub fn original_token(mut self, original_token: u32) -> Self {
self.original_token = Some(original_token);
self
}
#[must_use]
pub fn original_token_value(mut self, original_token: u32) -> Self {
self.original_token = Some(original_token);
self
}
pub fn build(self, assembly: &mut CilAssembly) -> Result<ChangeRefRc> {
let original_token = self.original_token.ok_or_else(|| {
Error::ModificationInvalid("Original token is required for EncMap".to_string())
})?;
let enc_map = EncMapRaw {
rid: 0,
token: Token::new(0),
offset: 0,
original_token: Token::new(original_token),
};
assembly.table_row_add(TableId::EncMap, TableDataOwned::EncMap(enc_map))
}
}
impl Default for EncMapBuilder {
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_encmap_builder_new() {
let builder = EncMapBuilder::new();
assert!(builder.original_token.is_none());
}
#[test]
fn test_encmap_builder_default() {
let builder = EncMapBuilder::default();
assert!(builder.original_token.is_none());
}
#[test]
fn test_encmap_builder_method_token() -> Result<()> {
let mut assembly = get_test_assembly()?;
let ref_ = EncMapBuilder::new()
.original_token(0x06000001) .build(&mut assembly)
.expect("Should build successfully");
assert_eq!(ref_.kind(), ChangeRefKind::TableRow(TableId::EncMap));
Ok(())
}
#[test]
fn test_encmap_builder_type_token() -> Result<()> {
let mut assembly = get_test_assembly()?;
let ref_ = EncMapBuilder::new()
.original_token(0x02000010) .build(&mut assembly)
.expect("Should build successfully");
assert_eq!(ref_.kind(), ChangeRefKind::TableRow(TableId::EncMap));
Ok(())
}
#[test]
fn test_encmap_builder_field_token() -> Result<()> {
let mut assembly = get_test_assembly()?;
let ref_ = EncMapBuilder::new()
.original_token(0x04000025) .build(&mut assembly)
.expect("Should build successfully");
assert_eq!(ref_.kind(), ChangeRefKind::TableRow(TableId::EncMap));
Ok(())
}
#[test]
fn test_encmap_builder_token_value() -> Result<()> {
let mut assembly = get_test_assembly()?;
let ref_ = EncMapBuilder::new()
.original_token_value(0x08000005)
.build(&mut assembly)
.expect("Should build successfully");
assert_eq!(ref_.kind(), ChangeRefKind::TableRow(TableId::EncMap));
Ok(())
}
#[test]
fn test_encmap_builder_missing_original_token() -> Result<()> {
let mut assembly = get_test_assembly()?;
let result = EncMapBuilder::new().build(&mut assembly);
assert!(result.is_err());
match result.unwrap_err() {
Error::ModificationInvalid(details) => {
assert!(details.contains("Original token is required"));
}
_ => panic!("Expected ModificationInvalid error"),
}
Ok(())
}
#[test]
fn test_encmap_builder_clone() {
let builder = EncMapBuilder::new().original_token(0x06000001);
let cloned = builder.clone();
assert_eq!(builder.original_token, cloned.original_token);
}
#[test]
fn test_encmap_builder_debug() {
let builder = EncMapBuilder::new().original_token(0x02000005);
let debug_str = format!("{builder:?}");
assert!(debug_str.contains("EncMapBuilder"));
assert!(debug_str.contains("original_token"));
}
#[test]
fn test_encmap_builder_fluent_interface() -> Result<()> {
let mut assembly = get_test_assembly()?;
let ref_ = EncMapBuilder::new()
.original_token(0x17000001) .build(&mut assembly)
.expect("Should build successfully");
assert_eq!(ref_.kind(), ChangeRefKind::TableRow(TableId::EncMap));
Ok(())
}
#[test]
fn test_encmap_builder_multiple_builds() -> Result<()> {
let mut assembly = get_test_assembly()?;
let ref1 = EncMapBuilder::new()
.original_token(0x06000001) .build(&mut assembly)
.expect("Should build first mapping entry");
let ref2 = EncMapBuilder::new()
.original_token(0x02000001) .build(&mut assembly)
.expect("Should build second mapping entry");
assert!(!std::sync::Arc::ptr_eq(&ref1, &ref2));
assert_eq!(ref1.kind(), ChangeRefKind::TableRow(TableId::EncMap));
assert_eq!(ref2.kind(), ChangeRefKind::TableRow(TableId::EncMap));
Ok(())
}
#[test]
fn test_encmap_builder_various_tokens() -> Result<()> {
let mut assembly = get_test_assembly()?;
let tokens = [
0x02000001, 0x06000001, 0x04000001, 0x08000001, 0x14000001, 0x17000001, ];
for &token_val in tokens.iter() {
let ref_ = EncMapBuilder::new()
.original_token(token_val)
.build(&mut assembly)
.expect("Should build successfully");
assert_eq!(ref_.kind(), ChangeRefKind::TableRow(TableId::EncMap));
}
Ok(())
}
#[test]
fn test_encmap_builder_large_token_values() -> Result<()> {
let mut assembly = get_test_assembly()?;
let large_tokens = [
0x06FFFFFF, 0x02FFFFFF, 0x04FFFFFF, ];
for &token_val in large_tokens.iter() {
let ref_ = EncMapBuilder::new()
.original_token(token_val)
.build(&mut assembly)
.expect("Should handle large token values");
assert_eq!(ref_.kind(), ChangeRefKind::TableRow(TableId::EncMap));
}
Ok(())
}
}