@@ -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 ) ) ]
198207pub 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
202225impl 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