1
- use md5:: { Context , Digest } ;
2
- use regex:: Regex ;
3
- use serde:: { Deserialize , Deserializer } ;
4
-
5
1
use crate :: error:: {
6
- CSVError , DuplicatePartitionsError , OverlappingPartitionsError , PartitionTableError ,
2
+ CSVError , DuplicatePartitionsError , InvalidSubTypeError , OverlappingPartitionsError ,
3
+ PartitionTableError ,
7
4
} ;
5
+ use md5:: { Context , Digest } ;
6
+ use regex:: Regex ;
7
+ use serde:: { Deserialize , Deserializer , Serialize } ;
8
8
use std:: cmp:: { max, min} ;
9
+ use std:: fmt:: Write as _;
10
+ use std:: fmt:: { Display , Formatter } ;
9
11
use std:: io:: Write ;
10
12
11
13
const MAX_PARTITION_LENGTH : usize = 0xC00 ;
12
14
const PARTITION_TABLE_SIZE : usize = 0x1000 ;
13
15
14
- #[ derive( Copy , Clone , Debug , Deserialize ) ]
16
+ #[ derive( Copy , Clone , Debug , Deserialize , Serialize , PartialEq ) ]
15
17
#[ repr( u8 ) ]
16
18
#[ allow( dead_code) ]
17
19
#[ serde( rename_all = "lowercase" ) ]
@@ -20,7 +22,46 @@ pub enum Type {
20
22
Data = 0x01 ,
21
23
}
22
24
23
- #[ derive( Copy , Clone , Debug , Deserialize , PartialEq ) ]
25
+ impl Type {
26
+ pub fn subtype_hint ( & self ) -> String {
27
+ match self {
28
+ Type :: App => "'factory', 'ota_0' trough 'ota_15' and 'test'" . into ( ) ,
29
+ Type :: Data => {
30
+ let types = [
31
+ DataType :: Ota ,
32
+ DataType :: Phy ,
33
+ DataType :: Nvs ,
34
+ DataType :: CoreDump ,
35
+ DataType :: NvsKeys ,
36
+ DataType :: EFuse ,
37
+ DataType :: EspHttpd ,
38
+ DataType :: Fat ,
39
+ DataType :: Spiffs ,
40
+ ] ;
41
+
42
+ let mut out = format ! ( "'{}'" , serde_plain:: to_string( & types[ 0 ] ) . unwrap( ) ) ;
43
+ for ty in & types[ 1 ..types. len ( ) - 2 ] {
44
+ let ser = serde_plain:: to_string ( & ty) . unwrap ( ) ;
45
+ write ! ( & mut out, ", '{}'" , ser) . unwrap ( ) ;
46
+ }
47
+
48
+ let ser = serde_plain:: to_string ( & types[ types. len ( ) - 1 ] ) . unwrap ( ) ;
49
+ write ! ( & mut out, " and '{}'" , ser) . unwrap ( ) ;
50
+
51
+ out
52
+ }
53
+ }
54
+ }
55
+ }
56
+
57
+ impl Display for Type {
58
+ fn fmt ( & self , f : & mut Formatter < ' _ > ) -> std:: fmt:: Result {
59
+ let ser = serde_plain:: to_string ( self ) . unwrap ( ) ;
60
+ write ! ( f, "{}" , ser)
61
+ }
62
+ }
63
+
64
+ #[ derive( Copy , Clone , Debug , Deserialize , Serialize , PartialEq ) ]
24
65
#[ repr( u8 ) ]
25
66
#[ allow( dead_code) ]
26
67
#[ serde( rename_all = "lowercase" ) ]
@@ -61,7 +102,7 @@ pub enum AppType {
61
102
Test = 0x20 ,
62
103
}
63
104
64
- #[ derive( Copy , Clone , Debug , Deserialize , PartialEq ) ]
105
+ #[ derive( Copy , Clone , Debug , Deserialize , Serialize , PartialEq ) ]
65
106
#[ repr( u8 ) ]
66
107
#[ allow( dead_code) ]
67
108
#[ serde( rename_all = "lowercase" ) ]
@@ -78,14 +119,25 @@ pub enum DataType {
78
119
Spiffs = 0x82 ,
79
120
}
80
121
81
- #[ derive( Debug , Deserialize , PartialEq ) ]
122
+ #[ derive( Debug , Deserialize , PartialEq , Copy , Clone ) ]
82
123
#[ allow( dead_code) ]
83
124
#[ serde( untagged) ]
84
125
pub enum SubType {
85
126
App ( AppType ) ,
86
127
Data ( DataType ) ,
87
128
}
88
129
130
+ impl Display for SubType {
131
+ fn fmt ( & self , f : & mut Formatter < ' _ > ) -> std:: fmt:: Result {
132
+ let ser = match self {
133
+ SubType :: App ( sub) => serde_plain:: to_string ( sub) ,
134
+ SubType :: Data ( sub) => serde_plain:: to_string ( sub) ,
135
+ }
136
+ . unwrap ( ) ;
137
+ write ! ( f, "{}" , ser)
138
+ }
139
+ }
140
+
89
141
impl SubType {
90
142
fn as_u8 ( & self ) -> u8 {
91
143
match self {
@@ -194,6 +246,24 @@ impl PartitionTable {
194
246
}
195
247
196
248
fn validate ( & self , source : & str ) -> Result < ( ) , PartitionTableError > {
249
+ for partition in & self . partitions {
250
+ if let Some ( line) = & partition. line {
251
+ let expected_type = match partition. sub_type {
252
+ SubType :: App ( _) => Type :: App ,
253
+ SubType :: Data ( _) => Type :: Data ,
254
+ } ;
255
+ if expected_type != partition. ty {
256
+ return Err ( InvalidSubTypeError :: new (
257
+ source,
258
+ * line,
259
+ partition. ty ,
260
+ partition. sub_type ,
261
+ )
262
+ . into ( ) ) ;
263
+ }
264
+ }
265
+ }
266
+
197
267
for partition1 in & self . partitions {
198
268
for partition2 in & self . partitions {
199
269
if let ( Some ( line1) , Some ( line2) ) = ( & partition1. line , & partition2. line ) {
0 commit comments