1use crate::PartitionError;
2
3#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
5pub enum PartitionType {
6 App(AppPartitionType),
8
9 Data(DataPartitionType),
11
12 #[default]
14 Any,
15
16 User(u8, u8),
18}
19
20impl From<AppPartitionType> for PartitionType {
21 fn from(subtype: AppPartitionType) -> Self {
22 Self::App(subtype)
23 }
24}
25
26impl From<DataPartitionType> for PartitionType {
27 fn from(subtype: DataPartitionType) -> Self {
28 Self::Data(subtype)
29 }
30}
31
32impl TryFrom<(u8, u8)> for PartitionType {
33 type Error = PartitionError;
34
35 fn try_from((raw_type, raw_subtype): (u8, u8)) -> Result<Self, Self::Error> {
36 Ok(match raw_type {
37 0x00 => Self::App(raw_subtype.try_into()?),
38 0x01 => Self::Data(raw_subtype.try_into()?),
39 0x40..=0xfe => Self::User(raw_type, raw_subtype),
40 0xff => Self::Any,
41 _ => return Err(PartitionError::InvalidType(raw_type)),
42 })
43 }
44}
45
46impl TryFrom<&[u8; 2]> for PartitionType {
47 type Error = PartitionError;
48
49 fn try_from([raw_type, raw_subtype]: &[u8; 2]) -> Result<Self, Self::Error> {
50 (*raw_type, *raw_subtype).try_into()
51 }
52}
53
54impl TryFrom<[u8; 2]> for PartitionType {
55 type Error = PartitionError;
56
57 fn try_from([raw_type, raw_subtype]: [u8; 2]) -> Result<Self, Self::Error> {
58 (raw_type, raw_subtype).try_into()
59 }
60}
61
62impl TryFrom<&[u8]> for PartitionType {
63 type Error = PartitionError;
64
65 fn try_from(slice: &[u8]) -> Result<Self, Self::Error> {
66 <[u8; 2]>::try_from(slice)
67 .map_err(|_| PartitionError::NotEnoughData)?
68 .try_into()
69 }
70}
71
72impl TryFrom<PartitionType> for (u8, u8) {
73 type Error = PartitionError;
74
75 fn try_from(ty: PartitionType) -> Result<Self, Self::Error> {
76 use PartitionType::*;
77 Ok(match ty {
78 App(subtype) => (0x00, subtype.try_into()?),
79 Data(subtype) => (0x01, subtype.into()),
80 User(usertype @ 0x40..=0xfe, subtype) => (usertype, subtype),
81 User(usertype, _) => return Err(PartitionError::InvalidUserType(usertype)),
82 Any => (0xff, 0x00),
83 })
84 }
85}
86
87impl TryFrom<PartitionType> for [u8; 2] {
88 type Error = PartitionError;
89
90 fn try_from(ty: PartitionType) -> Result<Self, Self::Error> {
91 let (type_, subtype) = ty.try_into()?;
92 Ok([type_, subtype])
93 }
94}
95
96impl PartitionType {
97 const APP_ALIGN: u32 = 0x10000;
99
100 const DATA_ALIGN: u32 = 0x1000;
102
103 pub fn align(&self) -> u32 {
105 match self {
106 PartitionType::App(_) => Self::APP_ALIGN,
107 _ => Self::DATA_ALIGN,
108 }
109 }
110
111 pub fn check_offset(&self, offset: u32) -> Result<(), PartitionError> {
113 if offset & (self.align() - 1) == 0 {
114 Ok(())
115 } else {
116 Err(PartitionError::InvalidAlignment)
117 }
118 }
119
120 pub fn from_bytes(data: &[u8; 2]) -> Result<Self, PartitionError> {
122 data.try_into()
123 }
124
125 pub fn to_bytes(&self, data: &mut [u8; 2]) -> Result<(), PartitionError> {
127 let (type_, subtype) = (*self).try_into()?;
128 data[0] = type_;
129 data[1] = subtype;
130 Ok(())
131 }
132}
133
134#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
136pub enum AppPartitionType {
137 #[default]
139 Factory,
140
141 Ota(u8),
143
144 Test,
146}
147
148impl TryFrom<u8> for AppPartitionType {
149 type Error = PartitionError;
150
151 fn try_from(raw: u8) -> Result<Self, Self::Error> {
152 Ok(match raw {
153 0x00 => Self::Factory,
154 0x10..=0x1f => Self::Ota(raw - 0x10),
155 0x20 => Self::Test,
156 _ => return Err(PartitionError::InvalidSubType(raw)),
157 })
158 }
159}
160
161impl TryFrom<AppPartitionType> for u8 {
162 type Error = PartitionError;
163
164 fn try_from(ty: AppPartitionType) -> Result<Self, Self::Error> {
165 use AppPartitionType::*;
166 Ok(match ty {
167 Factory => 0x00,
168 Ota(number @ 0x00..=0x0f) => number + 0x10,
169 Ota(number) => return Err(PartitionError::InvalidOtaNumber(number)),
170 Test => 0x20,
171 })
172 }
173}
174
175#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
177#[repr(u8)]
178pub enum DataPartitionType {
179 #[default]
181 Ota = 0x00,
182
183 Phy = 0x01,
185
186 Nvs = 0x02,
188
189 CoreDump = 0x03,
191
192 NvsKeys = 0x04,
194
195 EfuseEm = 0x05,
197
198 Undefined = 0x06,
200
201 EspHttpd = 0x80,
203
204 Fat = 0x81,
206
207 SpiFfs = 0x82,
209
210 LittleFS = 0x83,
212}
213
214impl TryFrom<u8> for DataPartitionType {
215 type Error = PartitionError;
216
217 fn try_from(raw: u8) -> Result<Self, Self::Error> {
218 Ok(match raw {
219 0x00 => Self::Ota,
220 0x01 => Self::Phy,
221 0x02 => Self::Nvs,
222 0x03 => Self::CoreDump,
223 0x04 => Self::NvsKeys,
224 0x05 => Self::EfuseEm,
225 0x06 => Self::Undefined,
226 0x80 => Self::EspHttpd,
227 0x81 => Self::Fat,
228 0x82 => Self::SpiFfs,
229 0x83 => Self::LittleFS,
230 _ => return Err(PartitionError::InvalidSubType(raw)),
231 })
232 }
233}
234
235impl From<DataPartitionType> for u8 {
236 fn from(ty: DataPartitionType) -> Self {
237 ty as _
238 }
239}