@@ -3,7 +3,6 @@ use std::{
3
3
fmt:: { Display , Formatter , Write as _} ,
4
4
io:: { Cursor , Write } ,
5
5
ops:: Rem ,
6
- str:: FromStr ,
7
6
} ;
8
7
9
8
use binread:: { BinRead , BinReaderExt } ;
@@ -12,7 +11,7 @@ use md5::{Context, Digest};
12
11
use regex:: Regex ;
13
12
use serde:: { Deserialize , Deserializer , Serialize } ;
14
13
use strum:: IntoEnumIterator ;
15
- use strum_macros:: { EnumIter , EnumString } ;
14
+ use strum_macros:: EnumIter ;
16
15
17
16
use crate :: error:: {
18
17
CSVError , DuplicatePartitionsError , InvalidChecksum , InvalidPartitionTable ,
@@ -96,73 +95,52 @@ impl Display for Type {
96
95
}
97
96
}
98
97
99
- #[ derive( Copy , Clone , Debug , Deserialize , Serialize , PartialEq , Eq , BinRead , EnumString ) ]
98
+ #[ derive( Copy , Clone , Debug , Deserialize , Serialize , PartialEq , Eq , BinRead ) ]
100
99
#[ repr( u8 ) ]
101
100
#[ br( little, repr = u8 ) ]
102
101
pub enum AppType {
103
102
#[ serde( rename = "factory" ) ]
104
- #[ strum( serialize = "factory" ) ]
105
103
Factory = 0x00 ,
106
104
#[ serde( rename = "ota_0" ) ]
107
- #[ strum( serialize = "ota_0" ) ]
108
105
Ota0 = 0x10 ,
109
106
#[ serde( rename = "ota_1" ) ]
110
- #[ strum( serialize = "ota_1" ) ]
111
107
Ota1 = 0x11 ,
112
108
#[ serde( rename = "ota_2" ) ]
113
- #[ strum( serialize = "ota_2" ) ]
114
109
Ota2 = 0x12 ,
115
110
#[ serde( rename = "ota_3" ) ]
116
- #[ strum( serialize = "ota_3" ) ]
117
111
Ota3 = 0x13 ,
118
112
#[ serde( rename = "ota_4" ) ]
119
- #[ strum( serialize = "ota_4" ) ]
120
113
Ota4 = 0x14 ,
121
114
#[ serde( rename = "ota_5" ) ]
122
- #[ strum( serialize = "ota_5" ) ]
123
115
Ota5 = 0x15 ,
124
116
#[ serde( rename = "ota_6" ) ]
125
- #[ strum( serialize = "ota_6" ) ]
126
117
Ota6 = 0x16 ,
127
118
#[ serde( rename = "ota_7" ) ]
128
- #[ strum( serialize = "ota_7" ) ]
129
119
Ota7 = 0x17 ,
130
120
#[ serde( rename = "ota_8" ) ]
131
- #[ strum( serialize = "ota_8" ) ]
132
121
Ota8 = 0x18 ,
133
122
#[ serde( rename = "ota_9" ) ]
134
- #[ strum( serialize = "ota_9" ) ]
135
123
Ota9 = 0x19 ,
136
124
#[ serde( rename = "ota_10" ) ]
137
- #[ strum( serialize = "ota_10" ) ]
138
125
Ota10 = 0x1a ,
139
126
#[ serde( rename = "ota_11" ) ]
140
- #[ strum( serialize = "ota_11" ) ]
141
127
Ota11 = 0x1b ,
142
128
#[ serde( rename = "ota_12" ) ]
143
- #[ strum( serialize = "ota_12" ) ]
144
129
Ota12 = 0x1c ,
145
130
#[ serde( rename = "ota_13" ) ]
146
- #[ strum( serialize = "ota_13" ) ]
147
131
Ota13 = 0x1d ,
148
132
#[ serde( rename = "ota_14" ) ]
149
- #[ strum( serialize = "ota_14" ) ]
150
133
Ota14 = 0x1e ,
151
134
#[ serde( rename = "ota_15" ) ]
152
- #[ strum( serialize = "ota_15" ) ]
153
135
Ota15 = 0x1f ,
154
136
#[ serde( rename = "test" ) ]
155
- #[ strum( serialize = "test" ) ]
156
137
Test = 0x20 ,
157
138
}
158
139
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 ) ]
162
141
#[ repr( u8 ) ]
163
142
#[ br( little, repr = u8 ) ]
164
143
#[ serde( rename_all = "lowercase" ) ]
165
- #[ strum( serialize_all = "lowercase" ) ]
166
144
pub enum DataType {
167
145
Ota = 0x00 ,
168
146
Phy = 0x01 ,
@@ -187,6 +165,7 @@ impl DataType {
187
165
pub enum SubType {
188
166
App ( AppType ) ,
189
167
Data ( DataType ) ,
168
+ #[ serde( deserialize_with = "deserialize_custom_partition_sub_type" ) ]
190
169
Custom ( u8 ) ,
191
170
}
192
171
@@ -376,7 +355,9 @@ impl PartitionTable {
376
355
return Ok ( table) ;
377
356
} else {
378
357
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
+
380
361
partitions. push ( part) ;
381
362
md5. consume ( line) ;
382
363
}
@@ -554,7 +535,6 @@ pub struct DeserializedPartition {
554
535
name : String ,
555
536
#[ serde( deserialize_with = "deserialize_partition_type" ) ]
556
537
ty : Type ,
557
- #[ serde( deserialize_with = "deserialize_partition_sub_type" ) ]
558
538
sub_type : SubType ,
559
539
#[ serde( deserialize_with = "deserialize_partition_offset" ) ]
560
540
offset : Option < u32 > ,
@@ -686,6 +666,12 @@ impl Partition {
686
666
self . flags
687
667
}
688
668
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
+
689
675
fn overlaps ( & self , other : & Partition ) -> bool {
690
676
max ( self . offset , other. offset ) < min ( self . offset + self . size , other. offset + other. size )
691
677
}
@@ -744,7 +730,7 @@ where
744
730
}
745
731
}
746
732
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 >
748
734
where
749
735
D : Deserializer < ' de > ,
750
736
{
@@ -753,15 +739,7 @@ where
753
739
let buf = String :: deserialize ( deserializer) ?;
754
740
let buf = buf. trim ( ) ;
755
741
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" ) ) )
765
743
}
766
744
767
745
fn deserialize_partition_offset_or_size < ' de , D > ( deserializer : D ) -> Result < Option < u32 > , D :: Error >
@@ -1034,6 +1012,25 @@ custom, 0x40, 0x00, 0xf00000, 0x100000,
1034
1012
assert_eq ! ( binary_parsed, csv_parsed) ;
1035
1013
}
1036
1014
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
+
1037
1034
#[ test]
1038
1035
fn blank_offsets_are_filled_in ( ) {
1039
1036
let pt2 = PartitionTable :: try_from_str ( PTABLE_2 )
0 commit comments