Skip to content

Commit c6c0e9b

Browse files
authored
Remove the dependency on hex (#820)
1 parent 8dea4e6 commit c6c0e9b

File tree

4 files changed

+49
-27
lines changed

4 files changed

+49
-27
lines changed

Cargo.lock

Lines changed: 0 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

espflash/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ directories = { version = "5.0.1", optional = true }
4141
env_logger = { version = "0.11.6", optional = true }
4242
esp-idf-part = "0.5.0"
4343
flate2 = "1.0.35"
44-
hex = { version = "0.4.3", features = ["serde"] }
4544
indicatif = { version = "0.17.9", optional = true }
4645
log = "0.4.22"
4746
md-5 = "0.10.6"

espflash/src/cli/config.rs

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -32,31 +32,32 @@ pub struct Connection {
3232
#[derive(Debug, Deserialize, Serialize, Default, Clone)]
3333
pub struct UsbDevice {
3434
/// USB Vendor ID
35-
#[serde(serialize_with = "parse_u16_hex", deserialize_with = "parse_hex_u16")]
35+
#[serde(
36+
serialize_with = "serialize_u16_to_hex",
37+
deserialize_with = "deserialize_hex_to_u16"
38+
)]
3639
pub vid: u16,
3740
/// USB Product ID
38-
#[serde(serialize_with = "parse_u16_hex", deserialize_with = "parse_hex_u16")]
41+
#[serde(
42+
serialize_with = "serialize_u16_to_hex",
43+
deserialize_with = "deserialize_hex_to_u16"
44+
)]
3945
pub pid: u16,
4046
}
4147

42-
fn parse_hex_u16<'de, D>(deserializer: D) -> Result<u16, D::Error>
48+
fn deserialize_hex_to_u16<'de, D>(deserializer: D) -> Result<u16, D::Error>
4349
where
4450
D: serde::Deserializer<'de>,
4551
{
46-
let s = String::deserialize(deserializer)?;
47-
let bytes = hex::decode(if s.len() % 2 == 1 {
48-
format!("0{}", s)
49-
} else {
50-
s
51-
})
52-
.map_err(serde::de::Error::custom)?;
53-
let padding = vec![0; 2_usize.saturating_sub(bytes.len())];
54-
let vec = [&padding[..], &bytes[..]].concat();
55-
let decimal = u16::from_be_bytes(vec.try_into().unwrap());
56-
Ok(decimal)
52+
let hex = String::deserialize(deserializer)?.to_lowercase();
53+
let hex = hex.trim_start_matches("0x");
54+
55+
let int = u16::from_str_radix(hex, 16).map_err(serde::de::Error::custom)?;
56+
57+
Ok(int)
5758
}
5859

59-
fn parse_u16_hex<S>(decimal: &u16, serializer: S) -> Result<S::Ok, S::Error>
60+
fn serialize_u16_to_hex<S>(decimal: &u16, serializer: S) -> Result<S::Ok, S::Error>
6061
where
6162
S: serde::Serializer,
6263
{
@@ -172,12 +173,15 @@ mod tests {
172173

173174
#[derive(Debug, Deserialize, Serialize)]
174175
struct TestData {
175-
#[serde(serialize_with = "parse_u16_hex", deserialize_with = "parse_hex_u16")]
176+
#[serde(
177+
serialize_with = "serialize_u16_to_hex",
178+
deserialize_with = "deserialize_hex_to_u16"
179+
)]
176180
value: u16,
177181
}
178182

179183
#[test]
180-
fn test_parse_hex_u16() {
184+
fn test_deserialize_hex_to_u16() {
181185
// Test no padding
182186
let result: Result<TestData, _> = toml::from_str(r#"value = "aaaa""#);
183187
assert_eq!(result.unwrap().value, 0xaaaa);
@@ -208,7 +212,7 @@ mod tests {
208212
}
209213

210214
#[test]
211-
fn test_parse_u16_hex() {
215+
fn test_serialize_u16_to_hex() {
212216
// Valid hexadecimal input with 1 digit
213217
let result: Result<TestData, _> = toml::from_str(r#"value = "1""#);
214218
assert_eq!(result.unwrap().value, 0x1);

espflash/src/image_format/esp_idf.rs

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ use std::{borrow::Cow, io::Write, iter::once, mem::size_of};
44

55
use bytemuck::{bytes_of, from_bytes, Pod, Zeroable};
66
use esp_idf_part::{AppType, DataType, Partition, PartitionTable, SubType, Type};
7-
use log::debug;
87
use sha2::{Digest, Sha256};
98
use xmas_elf::ElfFile;
109

@@ -181,10 +180,10 @@ impl<'a> IdfBootloaderFormat<'a> {
181180
let mut hasher = Sha256::new();
182181
hasher.update(&bootloader[..bootloader_sha_start]);
183182
let hash = hasher.finalize();
184-
debug!(
183+
log::debug!(
185184
"Updating bootloader SHA256 from {} to {}",
186-
hex::encode(&bootloader[bootloader_sha_start..bootloader_sha_end]),
187-
hex::encode(hash)
185+
encode_hex(&bootloader[bootloader_sha_start..bootloader_sha_end]),
186+
encode_hex(hash)
188187
);
189188
bootloader.to_mut()[bootloader_sha_start..bootloader_sha_end].copy_from_slice(&hash);
190189

@@ -481,6 +480,21 @@ fn update_checksum(data: &[u8], mut checksum: u8) -> u8 {
481480
checksum
482481
}
483482

483+
fn encode_hex<T>(data: T) -> String
484+
where
485+
T: AsRef<[u8]>,
486+
{
487+
const HEX_CHARS: &[u8] = b"0123456789abcdef";
488+
489+
let mut s = String::new();
490+
for byte in data.as_ref() {
491+
s.push(HEX_CHARS[(byte >> 4) as usize] as char);
492+
s.push(HEX_CHARS[(byte & 0x0F) as usize] as char);
493+
}
494+
495+
s
496+
}
497+
484498
#[cfg(test)]
485499
mod tests {
486500
use super::*;
@@ -498,4 +512,13 @@ mod tests {
498512
.unwrap();
499513
assert_eq!(header.flash_config, 0x5F);
500514
}
515+
516+
#[test]
517+
fn test_encode_hex() {
518+
assert_eq!(encode_hex(&[0u8]), "00");
519+
assert_eq!(encode_hex(&[10u8]), "0a");
520+
assert_eq!(encode_hex(&[255u8]), "ff");
521+
522+
assert_eq!(encode_hex(&[222u8, 202, 251, 173]), "decafbad");
523+
}
501524
}

0 commit comments

Comments
 (0)