1use crate::builder::BuildResult;
4use failure::Error;
5use ihex::Record;
6use std::{fs::File, io::Write, path::PathBuf};
7
8pub struct GenerateResult {
9 code: String,
10 eeprom: String,
11}
12
13fn generate_hex_from_segment(segment: &[u8]) -> Result<String, Error> {
14 let mut records = vec![];
15 if segment.len() > 0 {
16 records.push(Record::ExtendedSegmentAddress(0x0));
17
18 for (i, chunk) in segment.chunks(16).enumerate() {
19 records.push(Record::Data {
20 offset: i as u16 * 16,
21 value: chunk.to_vec(),
22 });
23 }
24 }
25 records.push(Record::EndOfFile);
26
27 let hex = ihex::create_object_file_representation(&records)?;
28
29 Ok(hex)
30}
31
32fn generate_hex(br: &BuildResult) -> Result<GenerateResult, Error> {
33 let code = generate_hex_from_segment(&br.code)?;
34
35 let eeprom = generate_hex_from_segment(&br.eeprom)?;
36
37 Ok(GenerateResult { code, eeprom })
38}
39
40pub fn write_code_hex(path: PathBuf, br: &BuildResult) -> Result<(), Error> {
41 let output = generate_hex(br)?;
42 let mut file_output = File::create(path)?;
43 file_output.write_all(output.code.replace("\n", "\r\n").as_bytes())?;
44 file_output.write(b"\r\n")?;
45
46 Ok(())
47}
48
49pub fn write_eeprom_hex(path: PathBuf, br: &BuildResult) -> Result<(), Error> {
50 let output = generate_hex(br)?;
51 let mut file_output = File::create(path)?;
52 file_output.write_all(output.eeprom.replace("\n", "\r\n").as_bytes())?;
53 file_output.write(b"\r\n")?;
54
55 Ok(())
56}
57
58#[cfg(test)]
59mod writer_tests {
60 use super::*;
61
62 #[test]
63 fn check_empty() {
64 let result = generate_hex(&BuildResult {
65 code: vec![],
66 eeprom: vec![],
67 flash_size: 4194304,
68 eeprom_size: 65536,
69 ram_size: 0,
70 ram_filling: 0,
71 messages: vec![],
72 })
73 .unwrap();
74
75 assert_eq!(result.code, ":00000001FF\n".to_string());
76 }
77
78 #[test]
79 fn check_code() {
80 let build_result = BuildResult {
81 code: vec![
82 0xf, 0x92, 0x10, 0x2d, 0x1f, 0x5f, 0xa, 0xf4, 0xfc, 0xcf, 0x1f, 0x90, 0xea, 0xe0,
83 0xf0, 0xe0, 0x5, 0x91, 0xb, 0xc0, 0xf, 0x1a, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x2c,
84 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x42, 0x0, 0x44, 0xff, 0x42, 0x0, 0x4e, 0xda,
85 0x22, 0xe1,
86 ],
87 eeprom: vec![],
88 flash_size: 0,
89 eeprom_size: 0,
90 ram_size: 0,
91 ram_filling: 0,
92 messages: vec![],
93 };
94
95 let result = generate_hex(&build_result).unwrap();
96
97 assert_eq!(
98 result.code,
99 ":020000020000FC
100:100000000F92102D1F5F0AF4FCCF1F90EAE0F0E082
101:1000100005910BC00F1A48656C6C6F2C20576F72DE
102:0C0020006C64420044FF42004EDA22E112
103:00000001FF\n"
104 .to_string()
105 );
106 }
107}