use crate::{
metadata::tables::{
statemachinemethod::StateMachineMethodRaw,
types::{RowWritable, TableInfoRef},
TableId,
},
utils::write_le_at_dyn,
Result,
};
impl RowWritable for StateMachineMethodRaw {
fn row_write(
&self,
data: &mut [u8],
offset: &mut usize,
_rid: u32,
sizes: &TableInfoRef,
) -> Result<()> {
write_le_at_dyn(
data,
offset,
self.move_next_method,
sizes.is_large(TableId::MethodDef),
)?;
write_le_at_dyn(
data,
offset,
self.kickoff_method,
sizes.is_large(TableId::MethodDef),
)?;
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{
metadata::tables::types::{RowReadable, TableInfo, TableRow},
metadata::token::Token,
};
#[test]
fn test_round_trip_serialization_small_table() {
let original_row = StateMachineMethodRaw {
rid: 1,
token: Token::new(0x3600_0001),
offset: 0,
move_next_method: 123,
kickoff_method: 45,
};
let table_info = std::sync::Arc::new(TableInfo::new_test(
&[(crate::metadata::tables::TableId::MethodDef, 1000)], false, false, false, ));
let row_size = <StateMachineMethodRaw as TableRow>::row_size(&table_info) as usize;
let mut buffer = vec![0u8; row_size];
let mut offset = 0;
original_row
.row_write(&mut buffer, &mut offset, 1, &table_info)
.expect("Serialization should succeed");
let mut read_offset = 0;
let deserialized_row =
StateMachineMethodRaw::row_read(&buffer, &mut read_offset, 1, &table_info)
.expect("Deserialization should succeed");
assert_eq!(
original_row.move_next_method,
deserialized_row.move_next_method
);
assert_eq!(original_row.kickoff_method, deserialized_row.kickoff_method);
assert_eq!(offset, row_size, "Offset should match expected row size");
assert_eq!(
read_offset, row_size,
"Read offset should match expected row size"
);
}
#[test]
fn test_round_trip_serialization_large_table() {
let original_row = StateMachineMethodRaw {
rid: 2,
token: Token::new(0x3600_0002),
offset: 0,
move_next_method: 0x1BEEF,
kickoff_method: 0x2CAFE,
};
let table_info = std::sync::Arc::new(TableInfo::new_test(
&[(crate::metadata::tables::TableId::MethodDef, 100000)], true, true, true, ));
let row_size = <StateMachineMethodRaw as TableRow>::row_size(&table_info) as usize;
let mut buffer = vec![0u8; row_size];
let mut offset = 0;
original_row
.row_write(&mut buffer, &mut offset, 2, &table_info)
.expect("Serialization should succeed");
let mut read_offset = 0;
let deserialized_row =
StateMachineMethodRaw::row_read(&buffer, &mut read_offset, 2, &table_info)
.expect("Deserialization should succeed");
assert_eq!(
original_row.move_next_method,
deserialized_row.move_next_method
);
assert_eq!(original_row.kickoff_method, deserialized_row.kickoff_method);
assert_eq!(offset, row_size, "Offset should match expected row size");
assert_eq!(
read_offset, row_size,
"Read offset should match expected row size"
);
}
#[test]
fn test_known_binary_format_small_table() {
let state_machine_method = StateMachineMethodRaw {
rid: 1,
token: Token::new(0x3600_0001),
offset: 0,
move_next_method: 0x1234,
kickoff_method: 0x5678,
};
let table_info = std::sync::Arc::new(TableInfo::new_test(
&[(crate::metadata::tables::TableId::MethodDef, 1000)], false, false, false, ));
let row_size = <StateMachineMethodRaw as TableRow>::row_size(&table_info) as usize;
let mut buffer = vec![0u8; row_size];
let mut offset = 0;
state_machine_method
.row_write(&mut buffer, &mut offset, 1, &table_info)
.expect("Serialization should succeed");
assert_eq!(row_size, 4, "Row size should be 4 bytes for small table");
assert_eq!(buffer[0], 0x34);
assert_eq!(buffer[1], 0x12);
assert_eq!(buffer[2], 0x78);
assert_eq!(buffer[3], 0x56);
}
#[test]
fn test_known_binary_format_large_table() {
let state_machine_method = StateMachineMethodRaw {
rid: 1,
token: Token::new(0x3600_0001),
offset: 0,
move_next_method: 0x12345678,
kickoff_method: 0x9ABCDEF0,
};
let table_info = std::sync::Arc::new(TableInfo::new_test(
&[(crate::metadata::tables::TableId::MethodDef, 100000)], true, true, true, ));
let row_size = <StateMachineMethodRaw as TableRow>::row_size(&table_info) as usize;
let mut buffer = vec![0u8; row_size];
let mut offset = 0;
state_machine_method
.row_write(&mut buffer, &mut offset, 1, &table_info)
.expect("Serialization should succeed");
assert_eq!(row_size, 8, "Row size should be 8 bytes for large table");
assert_eq!(buffer[0], 0x78);
assert_eq!(buffer[1], 0x56);
assert_eq!(buffer[2], 0x34);
assert_eq!(buffer[3], 0x12);
assert_eq!(buffer[4], 0xF0);
assert_eq!(buffer[5], 0xDE);
assert_eq!(buffer[6], 0xBC);
assert_eq!(buffer[7], 0x9A);
}
#[test]
fn test_async_method_mapping() {
let state_machine_method = StateMachineMethodRaw {
rid: 1,
token: Token::new(0x3600_0001),
offset: 0,
move_next_method: 100, kickoff_method: 50, };
let table_info = std::sync::Arc::new(TableInfo::new_test(
&[(crate::metadata::tables::TableId::MethodDef, 1000)],
false,
false,
false,
));
let row_size = <StateMachineMethodRaw as TableRow>::row_size(&table_info) as usize;
let mut buffer = vec![0u8; row_size];
let mut offset = 0;
state_machine_method
.row_write(&mut buffer, &mut offset, 1, &table_info)
.expect("Serialization should succeed");
let mut read_offset = 0;
let deserialized_row =
StateMachineMethodRaw::row_read(&buffer, &mut read_offset, 1, &table_info)
.expect("Deserialization should succeed");
assert_eq!(deserialized_row.move_next_method, 100);
assert_eq!(deserialized_row.kickoff_method, 50);
}
#[test]
fn test_yield_method_mapping() {
let state_machine_method = StateMachineMethodRaw {
rid: 1,
token: Token::new(0x3600_0001),
offset: 0,
move_next_method: 200, kickoff_method: 75, };
let table_info = std::sync::Arc::new(TableInfo::new_test(
&[(crate::metadata::tables::TableId::MethodDef, 1000)],
false,
false,
false,
));
let row_size = <StateMachineMethodRaw as TableRow>::row_size(&table_info) as usize;
let mut buffer = vec![0u8; row_size];
let mut offset = 0;
state_machine_method
.row_write(&mut buffer, &mut offset, 1, &table_info)
.expect("Serialization should succeed");
let mut read_offset = 0;
let deserialized_row =
StateMachineMethodRaw::row_read(&buffer, &mut read_offset, 1, &table_info)
.expect("Deserialization should succeed");
assert_eq!(deserialized_row.move_next_method, 200);
assert_eq!(deserialized_row.kickoff_method, 75);
}
#[test]
fn test_various_method_indices() {
let test_cases = vec![
(1, 1), (10, 5), (3, 15), (1000, 999), ];
for (move_next, kickoff) in test_cases {
let state_machine_method = StateMachineMethodRaw {
rid: 1,
token: Token::new(0x3600_0001),
offset: 0,
move_next_method: move_next,
kickoff_method: kickoff,
};
let table_info = std::sync::Arc::new(TableInfo::new_test(
&[(crate::metadata::tables::TableId::MethodDef, 2000)],
false,
false,
false,
));
let row_size = <StateMachineMethodRaw as TableRow>::row_size(&table_info) as usize;
let mut buffer = vec![0u8; row_size];
let mut offset = 0;
state_machine_method
.row_write(&mut buffer, &mut offset, 1, &table_info)
.expect("Serialization should succeed");
let mut read_offset = 0;
let deserialized_row =
StateMachineMethodRaw::row_read(&buffer, &mut read_offset, 1, &table_info)
.expect("Deserialization should succeed");
assert_eq!(deserialized_row.move_next_method, move_next);
assert_eq!(deserialized_row.kickoff_method, kickoff);
}
}
}