mint_cli/commands/
generate.rs

1use crate::args::Args;
2use crate::commands::stats::BlockStat;
3use crate::error::NvmError;
4use crate::layout;
5use crate::layout::args::BlockNames;
6use crate::layout::errors::LayoutError;
7use crate::layout::settings::Endianness;
8use crate::variant::DataSheet;
9use crate::writer::write_output;
10
11pub fn build_block_single(
12    input: &BlockNames,
13    data_sheet: Option<&DataSheet>,
14    args: &Args,
15) -> Result<BlockStat, NvmError> {
16    let result = (|| {
17        let layout = layout::load_layout(&input.file)?;
18
19        let block = layout
20            .blocks
21            .get(&input.name)
22            .ok_or(LayoutError::BlockNotFound(input.name.clone()))?;
23
24        let (bytestream, padding_bytes) =
25            block.build_bytestream(data_sheet, &layout.settings, args.layout.strict)?;
26
27        let data_range = crate::output::bytestream_to_datarange(
28            bytestream,
29            &block.header,
30            &layout.settings,
31            layout.settings.byte_swap,
32            layout.settings.pad_to_end,
33            padding_bytes,
34        )?;
35
36        let hex_string = crate::output::emit_hex(
37            std::slice::from_ref(&data_range),
38            args.output.record_width as usize,
39            args.output.format,
40        )?;
41
42        write_output(&args.output, &input.name, &hex_string)?;
43
44        let crc_value = match layout.settings.endianness {
45            Endianness::Big => u32::from_be_bytes([
46                data_range.crc_bytestream[0],
47                data_range.crc_bytestream[1],
48                data_range.crc_bytestream[2],
49                data_range.crc_bytestream[3],
50            ]),
51            Endianness::Little => u32::from_le_bytes([
52                data_range.crc_bytestream[0],
53                data_range.crc_bytestream[1],
54                data_range.crc_bytestream[2],
55                data_range.crc_bytestream[3],
56            ]),
57        };
58
59        Ok(BlockStat {
60            name: input.name.clone(),
61            start_address: data_range.start_address,
62            allocated_size: data_range.allocated_size,
63            used_size: data_range.used_size,
64            crc_value,
65        })
66    })();
67
68    result.map_err(|e| NvmError::InBlock {
69        block_name: input.name.clone(),
70        layout_file: input.file.clone(),
71        source: Box::new(e),
72    })
73}