@@ -80,71 +80,102 @@ impl<const SIZE: usize, RB: funty::Integral> ArrayRegisterData<SIZE, RB> {
8080 }
8181}
8282
83- impl < const SIZE : usize , RB : funty:: Integral > RegisterData < RB > for ArrayRegisterData < SIZE , RB > {
84- fn register ( & self , register : gimli:: Register ) -> Option < RB > {
85- let local_register_index = register. 0 . checked_sub ( self . starting_register_number ) ?;
86- self . registers . get ( local_register_index as usize ) . copied ( )
87- }
88- fn register_ref ( & self , register : gimli:: Register ) -> Option < & RB > {
89- let local_register_index = register. 0 . checked_sub ( self . starting_register_number ) ?;
90- self . registers . get ( local_register_index as usize )
91- }
92- fn register_mut ( & mut self , register : gimli:: Register ) -> Option < & mut RB > {
93- let local_register_index = register. 0 . checked_sub ( self . starting_register_number ) ?;
94- self . registers . get_mut ( local_register_index as usize )
95- }
96- }
97-
98- impl < const SIZE : usize , RB > FromIterator < u8 > for ArrayRegisterData < SIZE , RB >
83+ impl < const SIZE : usize , RB > ArrayRegisterData < SIZE , RB >
9984where
10085 RB : funty:: Integral ,
10186 RB :: Bytes : for < ' a > TryFrom < & ' a [ u8 ] > ,
10287{
103- fn from_iter < T : IntoIterator < Item = u8 > > ( iter : T ) -> Self {
104- // Get the iterator. We assume that it is in the same format as the bytes function outputs
88+ /// Try to build a [ArrayRegisterData] from an [IntoIterator<Item = u8>]
89+ pub fn try_from_iter < I : IntoIterator < Item = u8 > > (
90+ iter : I ,
91+ ) -> Result < Self , RegisterDataFromIterError > {
92+ use RegisterDataFromIterError :: * ;
93+ // Get the iterator.
10594 let mut iter = iter. into_iter ( ) ;
10695
107- assert_eq ! (
108- iter . next ( ) . unwrap ( ) ,
109- REGISTER_DATA_IDENTIFIER ,
110- "The given iterator is not for register data"
111- ) ;
96+ match iter . next ( ) {
97+ Some ( REGISTER_DATA_IDENTIFIER ) => { }
98+ Some ( id ) => return Err ( InvalidIdentifier ( id ) ) ,
99+ None => return Err ( NotEnoughItems ) ,
100+ }
112101
113102 // First the starting number is encoded
114- let starting_register_number =
115- u16:: from_le_bytes ( [ iter. next ( ) . unwrap ( ) , iter. next ( ) . unwrap ( ) ] ) ;
103+ let starting_register_number = u16:: from_le_bytes ( [
104+ iter. next ( ) . ok_or ( NotEnoughItems ) ?,
105+ iter. next ( ) . ok_or ( NotEnoughItems ) ?,
106+ ] ) ;
116107
117108 // Second is how many registers there are
118- let register_count = u16:: from_le_bytes ( [ iter. next ( ) . unwrap ( ) , iter. next ( ) . unwrap ( ) ] ) ;
109+ let register_count = u16:: from_le_bytes ( [
110+ iter. next ( ) . ok_or ( NotEnoughItems ) ?,
111+ iter. next ( ) . ok_or ( NotEnoughItems ) ?,
112+ ] ) ;
119113
120114 // Create the buffer we're storing the registers in
121115 let mut registers = ArrayVec :: new ( ) ;
122116
123117 // We process everything byte-by-byte generically so every register has an unknown length
124118 // So we need to store the bytes temporarily until we have enough to fully read the bytes as a register
125119 let register_size = core:: mem:: size_of :: < RB > ( ) ;
120+
121+ // Check that all register bytes will fit in `registers`
122+ let num_register_bytes = register_count as usize * register_size;
123+ if num_register_bytes > SIZE {
124+ return Err ( LengthTooBig ( register_count, register_size) ) ;
125+ }
126+
126127 let mut register_bytes_buffer = ArrayVec :: < u8 , 16 > :: new ( ) ;
127128
128- for byte in ( 0 ..register_count as usize * register_size) . map ( |_| iter. next ( ) . unwrap ( ) ) {
129- register_bytes_buffer. push ( byte) ;
129+ for byte in
130+ ( 0 ..num_register_bytes) . map ( |_| iter. next ( ) . ok_or ( NotEnoughItems ) )
131+ {
132+ let byte = byte?;
133+ register_bytes_buffer. try_push ( byte) . map_err ( |_| Corrupt ) ?;
130134
131135 if register_bytes_buffer. len ( ) == register_size {
132136 registers. push ( RB :: from_le_bytes (
133137 register_bytes_buffer
134138 . as_slice ( )
135139 . try_into ( )
136- . unwrap_or_else ( |_| panic ! ( ) ) ,
140+ . map_err ( |_| Corrupt ) ? ,
137141 ) ) ;
138142 register_bytes_buffer = ArrayVec :: new ( ) ;
139143 }
140144 }
141145
142- assert ! ( register_bytes_buffer. is_empty( ) ) ;
146+ if !register_bytes_buffer. is_empty ( ) {
147+ return Err ( Corrupt ) ;
148+ }
143149
144- Self {
150+ Ok ( Self {
145151 starting_register_number,
146152 registers,
147- }
153+ } )
154+ }
155+ }
156+
157+ impl < const SIZE : usize , RB : funty:: Integral > RegisterData < RB > for ArrayRegisterData < SIZE , RB > {
158+ fn register ( & self , register : gimli:: Register ) -> Option < RB > {
159+ let local_register_index = register. 0 . checked_sub ( self . starting_register_number ) ?;
160+ self . registers . get ( local_register_index as usize ) . copied ( )
161+ }
162+ fn register_ref ( & self , register : gimli:: Register ) -> Option < & RB > {
163+ let local_register_index = register. 0 . checked_sub ( self . starting_register_number ) ?;
164+ self . registers . get ( local_register_index as usize )
165+ }
166+ fn register_mut ( & mut self , register : gimli:: Register ) -> Option < & mut RB > {
167+ let local_register_index = register. 0 . checked_sub ( self . starting_register_number ) ?;
168+ self . registers . get_mut ( local_register_index as usize )
169+ }
170+ }
171+
172+ impl < const SIZE : usize , RB > FromIterator < u8 > for ArrayRegisterData < SIZE , RB >
173+ where
174+ RB : funty:: Integral ,
175+ RB :: Bytes : for < ' a > TryFrom < & ' a [ u8 ] > ,
176+ {
177+ fn from_iter < T : IntoIterator < Item = u8 > > ( iter : T ) -> Self {
178+ Self :: try_from_iter ( iter) . unwrap ( )
148179 }
149180}
150181
@@ -223,50 +254,76 @@ impl<RB: funty::Integral> RegisterData<RB> for VecRegisterData<RB> {
223254}
224255
225256#[ cfg( feature = "std" ) ]
226- impl < RB > FromIterator < u8 > for VecRegisterData < RB >
257+ impl < RB > VecRegisterData < RB >
227258where
228259 RB : funty:: Integral ,
229260 RB :: Bytes : for < ' a > TryFrom < & ' a [ u8 ] > ,
230261{
231- fn from_iter < T : IntoIterator < Item = u8 > > ( iter : T ) -> Self {
262+ /// Try to build a [VecRegisterData] from an [IntoIterator<Item = u8>]
263+ pub fn try_from_iter < I : IntoIterator < Item = u8 > > (
264+ iter : I ,
265+ ) -> Result < Self , RegisterDataFromIterError > {
266+ use RegisterDataFromIterError :: * ;
267+
232268 let mut iter = iter. into_iter ( ) ;
233269
234- assert_eq ! (
235- iter . next ( ) . unwrap ( ) ,
236- REGISTER_DATA_IDENTIFIER ,
237- "The given iterator is not for register data"
238- ) ;
270+ match iter . next ( ) {
271+ Some ( REGISTER_DATA_IDENTIFIER ) => { }
272+ Some ( id ) => return Err ( InvalidIdentifier ( id ) ) ,
273+ None => return Err ( NotEnoughItems ) ,
274+ }
239275
240- let starting_register_number =
241- u16:: from_le_bytes ( [ iter. next ( ) . unwrap ( ) , iter. next ( ) . unwrap ( ) ] ) ;
276+ let starting_register_number = u16:: from_le_bytes ( [
277+ iter. next ( ) . ok_or ( NotEnoughItems ) ?,
278+ iter. next ( ) . ok_or ( NotEnoughItems ) ?,
279+ ] ) ;
242280
243- let register_count = u16:: from_le_bytes ( [ iter. next ( ) . unwrap ( ) , iter. next ( ) . unwrap ( ) ] ) ;
281+ let register_count = u16:: from_le_bytes ( [
282+ iter. next ( ) . ok_or ( NotEnoughItems ) ?,
283+ iter. next ( ) . ok_or ( NotEnoughItems ) ?,
284+ ] ) ;
244285
245286 let mut registers = Vec :: new ( ) ;
246287 let register_size = core:: mem:: size_of :: < RB > ( ) ;
247288
248289 let mut register_bytes_buffer = ArrayVec :: < u8 , 16 > :: new ( ) ;
249290
250- for byte in ( 0 ..register_count as usize * register_size) . map ( |_| iter. next ( ) . unwrap ( ) ) {
251- register_bytes_buffer. push ( byte) ;
291+ for byte in
292+ ( 0 ..register_count as usize * register_size) . map ( |_| iter. next ( ) . ok_or ( NotEnoughItems ) )
293+ {
294+ let byte = byte?;
295+ register_bytes_buffer. try_push ( byte) . map_err ( |_| Corrupt ) ?;
252296
253297 if register_bytes_buffer. len ( ) == register_size {
254298 registers. push ( RB :: from_le_bytes (
255299 register_bytes_buffer
256300 . as_slice ( )
257301 . try_into ( )
258- . unwrap_or_else ( |_| panic ! ( ) ) ,
302+ . map_err ( |_| Corrupt ) ? ,
259303 ) ) ;
260304 register_bytes_buffer. clear ( ) ;
261305 }
262306 }
263307
264- assert ! ( register_bytes_buffer. is_empty( ) ) ;
308+ if !register_bytes_buffer. is_empty ( ) {
309+ return Err ( Corrupt ) ;
310+ }
265311
266- Self {
312+ Ok ( Self {
267313 starting_register_number,
268314 registers,
269- }
315+ } )
316+ }
317+ }
318+
319+ #[ cfg( feature = "std" ) ]
320+ impl < RB > FromIterator < u8 > for VecRegisterData < RB >
321+ where
322+ RB : funty:: Integral ,
323+ RB :: Bytes : for < ' a > TryFrom < & ' a [ u8 ] > ,
324+ {
325+ fn from_iter < T : IntoIterator < Item = u8 > > ( iter : T ) -> Self {
326+ Self :: try_from_iter ( iter) . unwrap ( )
270327 }
271328}
272329
@@ -324,6 +381,35 @@ impl<'a, RB: funty::Integral> Iterator for RegisterDataBytesIterator<'a, RB> {
324381
325382impl < ' a , RB : funty:: Integral > ExactSizeIterator for RegisterDataBytesIterator < ' a , RB > { }
326383
384+ #[ derive( Debug ) ]
385+ /// Specifies what went wrong building a [RegisterData] from an iterator
386+ pub enum RegisterDataFromIterError {
387+ /// The given iterator is not for a register set.
388+ /// First item from iterator yielded invalid identifier. Expected [REGISTER_DATA_IDENTIFIER]
389+ InvalidIdentifier ( u8 ) ,
390+ /// Iterator specified length too big for declared register set
391+ LengthTooBig ( u16 , usize ) ,
392+ /// Iterator did not yield enough items to build register set
393+ NotEnoughItems ,
394+ /// Iterator data is corrupt in some other way
395+ Corrupt ,
396+ }
397+
398+ impl core:: fmt:: Display for RegisterDataFromIterError {
399+ fn fmt ( & self , f : & mut core:: fmt:: Formatter < ' _ > ) -> core:: fmt:: Result {
400+ use RegisterDataFromIterError :: * ;
401+ match self {
402+ InvalidIdentifier ( id) => write ! ( f, "Iterator is not for a register set. Started with {id}, expected {REGISTER_DATA_IDENTIFIER}" ) ,
403+ LengthTooBig ( count, size) => write ! ( f, "Iterator specified length too big for register set: {len}" , len = * count as usize * size) ,
404+ NotEnoughItems => write ! ( f, "Iterator did not yield enough items to build register set" ) ,
405+ Corrupt => write ! ( f, "Iterator data is corrupt" )
406+ }
407+ }
408+ }
409+
410+ #[ cfg( feature = "std" ) ]
411+ impl std:: error:: Error for RegisterDataFromIterError { }
412+
327413#[ cfg( test) ]
328414mod tests {
329415 use super :: * ;
0 commit comments