Skip to content

Commit a1fcd8c

Browse files
committed
Improve handling of sub-types, no longer use strum_macros::EnumString
1 parent a8dab19 commit a1fcd8c

File tree

1 file changed

+34
-37
lines changed

1 file changed

+34
-37
lines changed

espflash/src/partition_table.rs

Lines changed: 34 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ use std::{
33
fmt::{Display, Formatter, Write as _},
44
io::{Cursor, Write},
55
ops::Rem,
6-
str::FromStr,
76
};
87

98
use binread::{BinRead, BinReaderExt};
@@ -12,7 +11,7 @@ use md5::{Context, Digest};
1211
use regex::Regex;
1312
use serde::{Deserialize, Deserializer, Serialize};
1413
use strum::IntoEnumIterator;
15-
use strum_macros::{EnumIter, EnumString};
14+
use strum_macros::EnumIter;
1615

1716
use crate::error::{
1817
CSVError, DuplicatePartitionsError, InvalidChecksum, InvalidPartitionTable,
@@ -96,73 +95,52 @@ impl Display for Type {
9695
}
9796
}
9897

99-
#[derive(Copy, Clone, Debug, Deserialize, Serialize, PartialEq, Eq, BinRead, EnumString)]
98+
#[derive(Copy, Clone, Debug, Deserialize, Serialize, PartialEq, Eq, BinRead)]
10099
#[repr(u8)]
101100
#[br(little, repr = u8)]
102101
pub enum AppType {
103102
#[serde(rename = "factory")]
104-
#[strum(serialize = "factory")]
105103
Factory = 0x00,
106104
#[serde(rename = "ota_0")]
107-
#[strum(serialize = "ota_0")]
108105
Ota0 = 0x10,
109106
#[serde(rename = "ota_1")]
110-
#[strum(serialize = "ota_1")]
111107
Ota1 = 0x11,
112108
#[serde(rename = "ota_2")]
113-
#[strum(serialize = "ota_2")]
114109
Ota2 = 0x12,
115110
#[serde(rename = "ota_3")]
116-
#[strum(serialize = "ota_3")]
117111
Ota3 = 0x13,
118112
#[serde(rename = "ota_4")]
119-
#[strum(serialize = "ota_4")]
120113
Ota4 = 0x14,
121114
#[serde(rename = "ota_5")]
122-
#[strum(serialize = "ota_5")]
123115
Ota5 = 0x15,
124116
#[serde(rename = "ota_6")]
125-
#[strum(serialize = "ota_6")]
126117
Ota6 = 0x16,
127118
#[serde(rename = "ota_7")]
128-
#[strum(serialize = "ota_7")]
129119
Ota7 = 0x17,
130120
#[serde(rename = "ota_8")]
131-
#[strum(serialize = "ota_8")]
132121
Ota8 = 0x18,
133122
#[serde(rename = "ota_9")]
134-
#[strum(serialize = "ota_9")]
135123
Ota9 = 0x19,
136124
#[serde(rename = "ota_10")]
137-
#[strum(serialize = "ota_10")]
138125
Ota10 = 0x1a,
139126
#[serde(rename = "ota_11")]
140-
#[strum(serialize = "ota_11")]
141127
Ota11 = 0x1b,
142128
#[serde(rename = "ota_12")]
143-
#[strum(serialize = "ota_12")]
144129
Ota12 = 0x1c,
145130
#[serde(rename = "ota_13")]
146-
#[strum(serialize = "ota_13")]
147131
Ota13 = 0x1d,
148132
#[serde(rename = "ota_14")]
149-
#[strum(serialize = "ota_14")]
150133
Ota14 = 0x1e,
151134
#[serde(rename = "ota_15")]
152-
#[strum(serialize = "ota_15")]
153135
Ota15 = 0x1f,
154136
#[serde(rename = "test")]
155-
#[strum(serialize = "test")]
156137
Test = 0x20,
157138
}
158139

159-
#[derive(
160-
Copy, Clone, Debug, Deserialize, EnumIter, Serialize, PartialEq, Eq, BinRead, EnumString,
161-
)]
140+
#[derive(Copy, Clone, Debug, Deserialize, EnumIter, Serialize, PartialEq, Eq, BinRead)]
162141
#[repr(u8)]
163142
#[br(little, repr = u8)]
164143
#[serde(rename_all = "lowercase")]
165-
#[strum(serialize_all = "lowercase")]
166144
pub enum DataType {
167145
Ota = 0x00,
168146
Phy = 0x01,
@@ -187,6 +165,7 @@ impl DataType {
187165
pub enum SubType {
188166
App(AppType),
189167
Data(DataType),
168+
#[serde(deserialize_with = "deserialize_custom_partition_sub_type")]
190169
Custom(u8),
191170
}
192171

@@ -376,7 +355,9 @@ impl PartitionTable {
376355
return Ok(table);
377356
} else {
378357
let mut reader = Cursor::new(line);
379-
let part: Partition = reader.read_le().unwrap();
358+
let mut part: Partition = reader.read_le().unwrap();
359+
part.fixup_sub_type();
360+
380361
partitions.push(part);
381362
md5.consume(line);
382363
}
@@ -554,7 +535,6 @@ pub struct DeserializedPartition {
554535
name: String,
555536
#[serde(deserialize_with = "deserialize_partition_type")]
556537
ty: Type,
557-
#[serde(deserialize_with = "deserialize_partition_sub_type")]
558538
sub_type: SubType,
559539
#[serde(deserialize_with = "deserialize_partition_offset")]
560540
offset: Option<u32>,
@@ -686,6 +666,12 @@ impl Partition {
686666
self.flags
687667
}
688668

669+
pub fn fixup_sub_type(&mut self) {
670+
if matches!(self.ty, Type::Custom(_)) && !matches!(self.sub_type, SubType::Custom(_)) {
671+
self.sub_type = SubType::Custom(self.sub_type.as_u8());
672+
}
673+
}
674+
689675
fn overlaps(&self, other: &Partition) -> bool {
690676
max(self.offset, other.offset) < min(self.offset + self.size, other.offset + other.size)
691677
}
@@ -744,7 +730,7 @@ where
744730
}
745731
}
746732

747-
fn deserialize_partition_sub_type<'de, D>(deserializer: D) -> Result<SubType, D::Error>
733+
fn deserialize_custom_partition_sub_type<'de, D>(deserializer: D) -> Result<u8, D::Error>
748734
where
749735
D: Deserializer<'de>,
750736
{
@@ -753,15 +739,7 @@ where
753739
let buf = String::deserialize(deserializer)?;
754740
let buf = buf.trim();
755741

756-
if let Ok(app_type) = AppType::from_str(buf) {
757-
Ok(SubType::App(app_type))
758-
} else if let Ok(data_type) = DataType::from_str(buf) {
759-
Ok(SubType::Data(data_type))
760-
} else if let Ok(int) = parse_int::parse::<u8>(buf) {
761-
Ok(SubType::Custom(int))
762-
} else {
763-
Err(Error::custom("invalid data sub-type"))
764-
}
742+
parse_int::parse::<u8>(buf).or(Err(Error::custom("invalid data sub-type")))
765743
}
766744

767745
fn deserialize_partition_offset_or_size<'de, D>(deserializer: D) -> Result<Option<u32>, D::Error>
@@ -1034,6 +1012,25 @@ custom, 0x40, 0x00, 0xf00000, 0x100000,
10341012
assert_eq!(binary_parsed, csv_parsed);
10351013
}
10361014

1015+
#[test]
1016+
fn test_from_csv_to_bin_and_back() {
1017+
let pt_basic = PartitionTable::try_from_str(PTABLE_0).unwrap();
1018+
1019+
let mut data = Vec::new();
1020+
pt_basic.save_bin(&mut data).unwrap();
1021+
let pt_from_bytes = PartitionTable::try_from_bytes(data).unwrap();
1022+
1023+
assert_eq!(pt_basic, pt_from_bytes);
1024+
1025+
let pt_custom = PartitionTable::try_from_str(PTABLE_CUSTOM_PARTITIONS).unwrap();
1026+
1027+
let mut data = Vec::new();
1028+
pt_custom.save_bin(&mut data).unwrap();
1029+
let pt_from_bytes = PartitionTable::try_from_bytes(data).unwrap();
1030+
1031+
assert_eq!(pt_custom, pt_from_bytes);
1032+
}
1033+
10371034
#[test]
10381035
fn blank_offsets_are_filled_in() {
10391036
let pt2 = PartitionTable::try_from_str(PTABLE_2)

0 commit comments

Comments
 (0)