Skip to content

Commit 98ca3ab

Browse files
authored
ucsi/lpm: Add iterator over GET_PDOS content (#51)
* Also fix PDO count * Add PDO length constant Breaking due to making `raw` private.
1 parent e8a43c8 commit 98ca3ab

File tree

2 files changed

+78
-6
lines changed

2 files changed

+78
-6
lines changed

src/pdo/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ pub const MW500_UNIT: u32 = 500;
3333
/// 1000 mW unit
3434
pub const MW1000_UNIT: u32 = 1000;
3535

36+
/// Length of a PDO in bytes
37+
pub const PDO_LEN: usize = 4;
38+
3639
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
3740
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
3841
pub enum PdoKind {

src/ucsi/lpm/get_pdos.rs

Lines changed: 75 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -125,12 +125,21 @@ impl Args {
125125
}
126126

127127
pub fn num_pdos(&self) -> u8 {
128-
self.0.num_pdos()
128+
// +1 as per UCSI spec
129+
self.0.num_pdos() + 1
129130
}
130131

131-
pub fn set_num_pdos(&mut self, num_pdos: u8) -> &mut Self {
132-
self.0.set_num_pdos(num_pdos);
133-
self
132+
/// Sets the number of PDOs to retrieve, must be in range 1..=MAX_PDOS
133+
///
134+
/// Returns `None` if the value is out of range
135+
pub fn set_num_pdos(&mut self, num_pdos: u8) -> Option<&mut Self> {
136+
if num_pdos == 0 || num_pdos > MAX_PDOS as u8 {
137+
return None;
138+
}
139+
140+
// -1 as per UCSI spec
141+
self.0.set_num_pdos(num_pdos - 1);
142+
Some(self)
134143
}
135144

136145
pub fn role(&self) -> PowerRole {
@@ -196,7 +205,21 @@ impl<Context> Decode<Context> for Args {
196205
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
197206
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
198207
pub struct ResponseData {
199-
pub raw: [u32; MAX_PDOS],
208+
raw: [u32; MAX_PDOS],
209+
}
210+
211+
impl ResponseData {
212+
/// Iterator over valid PDOs
213+
pub fn iter(&self) -> impl ExactSizeIterator<Item = u32> + '_ {
214+
let last_pdo = self.raw.iter().position(|&pdo| pdo == 0).unwrap_or(self.raw.len());
215+
self.raw.as_slice()[..last_pdo].iter().copied()
216+
}
217+
218+
/// Mutable iterator over valid PDOs
219+
pub fn iter_mut(&mut self) -> impl ExactSizeIterator<Item = &mut u32> + '_ {
220+
let last_pdo = self.raw.iter().position(|&pdo| pdo == 0).unwrap_or(self.raw.len());
221+
self.raw.as_mut_slice()[..last_pdo].iter_mut()
222+
}
200223
}
201224

202225
impl Encode for ResponseData {
@@ -242,7 +265,7 @@ mod test {
242265
#[test]
243266
fn test_decode_args() {
244267
// Partner, connector 3, 1 PDO, source, maximum capabilities, offset 4
245-
let encoded: [u8; 6] = [0x83, 0x04, 0x15, 0x00, 0x00, 0x00];
268+
let encoded: [u8; 6] = [0x83, 0x04, 0x14, 0x00, 0x00, 0x00];
246269
let (decoded, size): (Args, usize) = decode_from_slice(&encoded, standard().with_fixed_int_encoding()).unwrap();
247270
assert_eq!(size, 6);
248271

@@ -251,8 +274,54 @@ mod test {
251274
.set_partner(true)
252275
.set_pdo_offset(4)
253276
.set_num_pdos(1)
277+
.unwrap()
254278
.set_role(PowerRole::Source)
255279
.set_source_capability_type(SourceCapabilityType::Maximum);
256280
assert_eq!(decoded, expected);
257281
}
282+
283+
#[test]
284+
fn test_response_iterator() {
285+
let response = ResponseData {
286+
raw: [0x12, 0x34, 0x56, 0x00],
287+
};
288+
let mut iter = response.iter();
289+
assert_eq!(iter.len(), 3);
290+
assert_eq!(iter.next(), Some(0x12));
291+
assert_eq!(iter.len(), 2);
292+
assert_eq!(iter.next(), Some(0x34));
293+
assert_eq!(iter.len(), 1);
294+
assert_eq!(iter.next(), Some(0x56));
295+
assert_eq!(iter.len(), 0);
296+
assert_eq!(iter.next(), None);
297+
assert_eq!(iter.len(), 0);
298+
}
299+
300+
#[test]
301+
fn test_response_iterator_empty() {
302+
let response = ResponseData { raw: [0x00; MAX_PDOS] };
303+
let mut iter = response.iter();
304+
assert_eq!(iter.len(), 0);
305+
assert_eq!(iter.next(), None);
306+
assert_eq!(iter.len(), 0);
307+
}
308+
309+
#[test]
310+
fn test_response_iterator_full() {
311+
let response = ResponseData {
312+
raw: [0x12, 0x34, 0x56, 0x78],
313+
};
314+
let mut iter = response.iter();
315+
assert_eq!(iter.len(), 4);
316+
assert_eq!(iter.next(), Some(0x12));
317+
assert_eq!(iter.len(), 3);
318+
assert_eq!(iter.next(), Some(0x34));
319+
assert_eq!(iter.len(), 2);
320+
assert_eq!(iter.next(), Some(0x56));
321+
assert_eq!(iter.len(), 1);
322+
assert_eq!(iter.next(), Some(0x78));
323+
assert_eq!(iter.len(), 0);
324+
assert_eq!(iter.next(), None);
325+
assert_eq!(iter.len(), 0);
326+
}
258327
}

0 commit comments

Comments
 (0)