use std::io::Write;
#[path = "common/mod.rs"]
mod common;
fn bitmap_layout(data_content: &str) -> String {
format!(
r#"
[mint]
endianness = "little"
[block.header]
start_address = 0x80000
length = 0x100
padding = 0x00
[block.data]
{data_content}
"#
)
}
#[test]
fn bitmap_u8_literal_values() {
common::ensure_out_dir();
let layout = bitmap_layout(
r#"flags = { type = "u8", bitmap = [
{ bits = 1, value = 1 },
{ bits = 2, value = 3 },
{ bits = 5, value = 21 },
] }"#,
);
let path = std::path::Path::new("out").join("test_bitmap_u8.toml");
std::fs::File::create(&path)
.unwrap()
.write_all(layout.as_bytes())
.unwrap();
let cfg = mint_core::layout::load_layout(path.to_str().unwrap()).expect("parse");
let block = cfg.blocks.get("block").expect("block");
let (bytes, _) = common::build_block(block, &cfg.mint, false, None).expect("build");
assert_eq!(bytes[0], 0xAF, "u8 bitmap packing: got {:#04x}", bytes[0]);
}
#[test]
fn bitmap_u16_little_endian() {
common::ensure_out_dir();
let layout = bitmap_layout(
r#"val = { type = "u16", bitmap = [
{ bits = 8, value = 0xAB },
{ bits = 8, value = 0xCD },
] }"#,
);
let path = std::path::Path::new("out").join("test_bitmap_u16_le.toml");
std::fs::File::create(&path)
.unwrap()
.write_all(layout.as_bytes())
.unwrap();
let cfg = mint_core::layout::load_layout(path.to_str().unwrap()).expect("parse");
let block = cfg.blocks.get("block").expect("block");
let (bytes, _) = common::build_block(block, &cfg.mint, false, None).expect("build");
assert_eq!(&bytes[0..2], &[0xAB, 0xCD], "u16 LE bitmap");
}
#[test]
fn bitmap_i16_signed_negative_values() {
common::ensure_out_dir();
let layout = bitmap_layout(
r#"flags = { type = "i16", bitmap = [
{ bits = 4, value = -1 },
{ bits = 4, value = -8 },
{ bits = 8, value = 0 },
] }"#,
);
let path = std::path::Path::new("out").join("test_bitmap_i16_signed.toml");
std::fs::File::create(&path)
.unwrap()
.write_all(layout.as_bytes())
.unwrap();
let cfg = mint_core::layout::load_layout(path.to_str().unwrap()).expect("parse");
let block = cfg.blocks.get("block").expect("block");
let (bytes, _) = common::build_block(block, &cfg.mint, false, None).expect("build");
assert_eq!(
&bytes[0..2],
&[0x8F, 0x00],
"i16 signed bitmap: got {:02x?}",
&bytes[0..2]
);
}
#[test]
fn bitmap_signed_storage_preserves_high_bit_patterns() {
common::ensure_out_dir();
let i8_layout = bitmap_layout(
r#"flags = { type = "i8", bitmap = [
{ bits = 8, value = -1 },
] }"#,
);
let i8_path = common::write_layout_file("bitmap_i8_high_bit", &i8_layout);
let i8_cfg = mint_core::layout::load_layout(&i8_path).expect("parse");
let i8_block = i8_cfg.blocks.get("block").expect("block");
let (i8_bytes, _) = common::build_block(i8_block, &i8_cfg.mint, false, None).expect("build");
assert_eq!(&i8_bytes[0..1], &[0xFF]);
let i16_layout = bitmap_layout(
r#"flags = { type = "i16", bitmap = [
{ bits = 16, value = -32768 },
] }"#,
);
let i16_path = common::write_layout_file("bitmap_i16_high_bit", &i16_layout);
let i16_cfg = mint_core::layout::load_layout(&i16_path).expect("parse");
let i16_block = i16_cfg.blocks.get("block").expect("block");
let (i16_bytes, _) = common::build_block(i16_block, &i16_cfg.mint, false, None).expect("build");
assert_eq!(&i16_bytes[0..2], &[0x00, 0x80]);
}
#[test]
fn bitmap_u32_mixed_fields() {
common::ensure_out_dir();
let layout = bitmap_layout(
r#"status = { type = "u32", bitmap = [
{ bits = 1, value = true },
{ bits = 8, value = 255 },
{ bits = 23, value = 0 },
] }"#,
);
let path = std::path::Path::new("out").join("test_bitmap_u32.toml");
std::fs::File::create(&path)
.unwrap()
.write_all(layout.as_bytes())
.unwrap();
let cfg = mint_core::layout::load_layout(path.to_str().unwrap()).expect("parse");
let block = cfg.blocks.get("block").expect("block");
let (bytes, _) = common::build_block(block, &cfg.mint, false, None).expect("build");
assert_eq!(
&bytes[0..4],
&[0xFF, 0x01, 0x00, 0x00],
"u32 bitmap: got {:02x?}",
&bytes[0..4]
);
}
#[test]
fn bitmap_saturation_non_strict() {
common::ensure_out_dir();
let layout = bitmap_layout(
r#"sat = { type = "u8", bitmap = [
{ bits = 3, value = 10 },
{ bits = 5, value = 0 },
] }"#,
);
let path = std::path::Path::new("out").join("test_bitmap_saturate.toml");
std::fs::File::create(&path)
.unwrap()
.write_all(layout.as_bytes())
.unwrap();
let cfg = mint_core::layout::load_layout(path.to_str().unwrap()).expect("parse");
let block = cfg.blocks.get("block").expect("block");
let (bytes, _) = common::build_block(block, &cfg.mint, false, None)
.expect("saturation should succeed in non-strict");
assert_eq!(bytes[0], 7, "3-bit field saturates 10 to 7");
}
#[test]
fn bitmap_strict_rejects_out_of_range() {
common::ensure_out_dir();
let layout = bitmap_layout(
r#"bad = { type = "u8", bitmap = [
{ bits = 3, value = 10 },
{ bits = 5, value = 0 },
] }"#,
);
let path = std::path::Path::new("out").join("test_bitmap_strict_range.toml");
std::fs::File::create(&path)
.unwrap()
.write_all(layout.as_bytes())
.unwrap();
let cfg = mint_core::layout::load_layout(path.to_str().unwrap()).expect("parse");
let block = cfg.blocks.get("block").expect("block");
let res = common::build_block(block, &cfg.mint, true, None);
assert!(res.is_err(), "strict mode rejects out-of-range value");
}
#[test]
fn bitmap_rejects_wrong_bit_sum() {
common::ensure_out_dir();
let layout = bitmap_layout(
r#"bad = { type = "u8", bitmap = [
{ bits = 3, value = 0 },
{ bits = 4, value = 0 },
] }"#,
);
let path = std::path::Path::new("out").join("test_bitmap_bad_sum.toml");
std::fs::File::create(&path)
.unwrap()
.write_all(layout.as_bytes())
.unwrap();
let cfg = mint_core::layout::load_layout(path.to_str().unwrap()).expect("parse");
let block = cfg.blocks.get("block").expect("block");
let res = common::build_block(block, &cfg.mint, false, None);
assert!(res.is_err(), "bitmap with wrong bit sum should error");
}
#[test]
fn bitmap_rejects_zero_bits() {
common::ensure_out_dir();
let layout = bitmap_layout(
r#"bad = { type = "u8", bitmap = [
{ bits = 0, value = 0 },
{ bits = 8, value = 0 },
] }"#,
);
let path = std::path::Path::new("out").join("test_bitmap_zero_bits.toml");
std::fs::File::create(&path)
.unwrap()
.write_all(layout.as_bytes())
.unwrap();
let cfg = mint_core::layout::load_layout(path.to_str().unwrap()).expect("parse");
let block = cfg.blocks.get("block").expect("block");
let res = common::build_block(block, &cfg.mint, false, None);
assert!(res.is_err(), "bitmap with zero-bit field should error");
}
#[test]
fn bitmap_rejects_float_storage() {
common::ensure_out_dir();
let layout = bitmap_layout(
r#"bad = { type = "f32", bitmap = [
{ bits = 16, value = 0 },
{ bits = 16, value = 0 },
] }"#,
);
let path = std::path::Path::new("out").join("test_bitmap_float.toml");
std::fs::File::create(&path)
.unwrap()
.write_all(layout.as_bytes())
.unwrap();
let cfg = mint_core::layout::load_layout(path.to_str().unwrap()).expect("parse");
let block = cfg.blocks.get("block").expect("block");
let res = common::build_block(block, &cfg.mint, false, None);
assert!(res.is_err(), "bitmap with float storage should error");
}
#[test]
fn bitmap_rejects_size_key() {
common::ensure_out_dir();
let layout = bitmap_layout(
r#"bad = { type = "u8", size = 2, bitmap = [
{ bits = 8, value = 0 },
] }"#,
);
let path = std::path::Path::new("out").join("test_bitmap_size_key.toml");
std::fs::File::create(&path)
.unwrap()
.write_all(layout.as_bytes())
.unwrap();
let cfg = mint_core::layout::load_layout(path.to_str().unwrap()).expect("parse");
let block = cfg.blocks.get("block").expect("block");
let res = common::build_block(block, &cfg.mint, false, None);
assert!(res.is_err(), "bitmap with size key should error");
}