use crate::{
metadata::tables::{
fieldlayout::FieldLayoutRaw,
types::{RowWritable, TableId, TableInfoRef},
},
utils::{write_le_at, write_le_at_dyn},
Result,
};
impl RowWritable for FieldLayoutRaw {
fn row_write(
&self,
data: &mut [u8],
offset: &mut usize,
_rid: u32,
sizes: &TableInfoRef,
) -> Result<()> {
write_le_at(data, offset, self.field_offset)?;
write_le_at_dyn(data, offset, self.field, sizes.is_large(TableId::Field))?;
Ok(())
}
}
#[cfg(test)]
mod tests {
use std::sync::Arc;
use crate::metadata::tables::{
fieldlayout::FieldLayoutRaw,
types::{RowReadable, RowWritable, TableId, TableInfo, TableRow},
};
use crate::metadata::token::Token;
#[test]
fn test_fieldlayout_row_size() {
let sizes = Arc::new(TableInfo::new_test(
&[(TableId::Field, 100)],
false,
false,
false,
));
let expected_size = 4 + 2; assert_eq!(
<FieldLayoutRaw as TableRow>::row_size(&sizes),
expected_size
);
let sizes_large = Arc::new(TableInfo::new_test(
&[(TableId::Field, 0x10000)],
false,
false,
false,
));
let expected_size_large = 4 + 4; assert_eq!(
<FieldLayoutRaw as TableRow>::row_size(&sizes_large),
expected_size_large
);
}
#[test]
fn test_fieldlayout_row_write_small() {
let sizes = Arc::new(TableInfo::new_test(
&[(TableId::Field, 100)],
false,
false,
false,
));
let field_layout = FieldLayoutRaw {
rid: 1,
token: Token::new(0x10000001),
offset: 0,
field_offset: 0x01010101,
field: 0x0202,
};
let mut buffer = vec![0u8; <FieldLayoutRaw as TableRow>::row_size(&sizes) as usize];
let mut offset = 0;
field_layout
.row_write(&mut buffer, &mut offset, 1, &sizes)
.unwrap();
let expected = vec![
0x01, 0x01, 0x01, 0x01, 0x02, 0x02, ];
assert_eq!(buffer, expected);
assert_eq!(offset, expected.len());
}
#[test]
fn test_fieldlayout_row_write_large() {
let sizes = Arc::new(TableInfo::new_test(
&[(TableId::Field, 0x10000)],
false,
false,
false,
));
let field_layout = FieldLayoutRaw {
rid: 1,
token: Token::new(0x10000001),
offset: 0,
field_offset: 0x01010101,
field: 0x02020202,
};
let mut buffer = vec![0u8; <FieldLayoutRaw as TableRow>::row_size(&sizes) as usize];
let mut offset = 0;
field_layout
.row_write(&mut buffer, &mut offset, 1, &sizes)
.unwrap();
let expected = vec![
0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, ];
assert_eq!(buffer, expected);
assert_eq!(offset, expected.len());
}
#[test]
fn test_fieldlayout_round_trip() {
let sizes = Arc::new(TableInfo::new_test(
&[(TableId::Field, 100)],
false,
false,
false,
));
let original = FieldLayoutRaw {
rid: 42,
token: Token::new(0x1000002A),
offset: 0,
field_offset: 16, field: 25, };
let mut buffer = vec![0u8; <FieldLayoutRaw as TableRow>::row_size(&sizes) as usize];
let mut offset = 0;
original
.row_write(&mut buffer, &mut offset, 42, &sizes)
.unwrap();
let mut read_offset = 0;
let read_back = FieldLayoutRaw::row_read(&buffer, &mut read_offset, 42, &sizes).unwrap();
assert_eq!(original.rid, read_back.rid);
assert_eq!(original.token, read_back.token);
assert_eq!(original.field_offset, read_back.field_offset);
assert_eq!(original.field, read_back.field);
}
#[test]
fn test_fieldlayout_different_offsets() {
let sizes = Arc::new(TableInfo::new_test(
&[(TableId::Field, 100)],
false,
false,
false,
));
let test_cases = vec![
(0, 1), (4, 2), (8, 3), (16, 4), (32, 5), (64, 6), (128, 7), (256, 8), ];
for (field_offset, field_index) in test_cases {
let field_layout = FieldLayoutRaw {
rid: 1,
token: Token::new(0x10000001),
offset: 0,
field_offset,
field: field_index,
};
let mut buffer = vec![0u8; <FieldLayoutRaw as TableRow>::row_size(&sizes) as usize];
let mut offset = 0;
field_layout
.row_write(&mut buffer, &mut offset, 1, &sizes)
.unwrap();
let mut read_offset = 0;
let read_back = FieldLayoutRaw::row_read(&buffer, &mut read_offset, 1, &sizes).unwrap();
assert_eq!(field_layout.field_offset, read_back.field_offset);
assert_eq!(field_layout.field, read_back.field);
}
}
#[test]
fn test_fieldlayout_edge_cases() {
let sizes = Arc::new(TableInfo::new_test(
&[(TableId::Field, 100)],
false,
false,
false,
));
let zero_layout = FieldLayoutRaw {
rid: 1,
token: Token::new(0x10000001),
offset: 0,
field_offset: 0,
field: 0,
};
let mut buffer = vec![0u8; <FieldLayoutRaw as TableRow>::row_size(&sizes) as usize];
let mut offset = 0;
zero_layout
.row_write(&mut buffer, &mut offset, 1, &sizes)
.unwrap();
let expected = vec![
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ];
assert_eq!(buffer, expected);
let max_layout = FieldLayoutRaw {
rid: 1,
token: Token::new(0x10000001),
offset: 0,
field_offset: 0xFFFFFFFF,
field: 0xFFFF,
};
let mut buffer = vec![0u8; <FieldLayoutRaw as TableRow>::row_size(&sizes) as usize];
let mut offset = 0;
max_layout
.row_write(&mut buffer, &mut offset, 1, &sizes)
.unwrap();
assert_eq!(buffer.len(), 6); }
#[test]
fn test_fieldlayout_alignment_scenarios() {
let sizes = Arc::new(TableInfo::new_test(
&[(TableId::Field, 100)],
false,
false,
false,
));
let alignment_cases = vec![
(0, 1), (1, 2), (2, 3), (4, 4), (8, 5), (16, 6), (32, 7), (48, 8), (63, 9), ];
for (field_offset, field_index) in alignment_cases {
let field_layout = FieldLayoutRaw {
rid: 1,
token: Token::new(0x10000001),
offset: 0,
field_offset,
field: field_index,
};
let mut buffer = vec![0u8; <FieldLayoutRaw as TableRow>::row_size(&sizes) as usize];
let mut offset = 0;
field_layout
.row_write(&mut buffer, &mut offset, 1, &sizes)
.unwrap();
let written_offset = u32::from_le_bytes([buffer[0], buffer[1], buffer[2], buffer[3]]);
assert_eq!(written_offset, field_offset);
let written_field = u16::from_le_bytes([buffer[4], buffer[5]]);
assert_eq!(written_field as u32, field_index);
}
}
#[test]
fn test_fieldlayout_known_binary_format() {
let sizes = Arc::new(TableInfo::new_test(
&[(TableId::Field, 1)],
false,
false,
false,
));
let field_layout = FieldLayoutRaw {
rid: 1,
token: Token::new(0x10000001),
offset: 0,
field_offset: 0x01010101,
field: 0x0202,
};
let mut buffer = vec![0u8; <FieldLayoutRaw as TableRow>::row_size(&sizes) as usize];
let mut offset = 0;
field_layout
.row_write(&mut buffer, &mut offset, 1, &sizes)
.unwrap();
let expected = vec![
0x01, 0x01, 0x01, 0x01, 0x02, 0x02, ];
assert_eq!(buffer, expected);
}
}