@@ -103,6 +103,56 @@ impl<const SIZE: usize> ArrayMemoryRegion<SIZE> {
103103        self . data . set_len ( data_len) ; 
104104        self . data . as_mut_ptr ( ) . copy_from ( data_ptr,  data_len) ; 
105105    } 
106+ 
107+     /// Try to build a [ArrayMemoryRegion] from an [IntoIterator<Item = u8>] 
108+      pub  fn  try_from_iter < I :  IntoIterator < Item  = u8 > > ( 
109+         iter :  I , 
110+     )  -> Result < Self ,  MemoryRegionFromIterError >  { 
111+         use  MemoryRegionFromIterError :: * ; 
112+         let  mut  iter = iter. into_iter ( ) ; 
113+ 
114+         match  iter. next ( )  { 
115+             Some ( MEMORY_REGION_IDENTIFIER )  => { } 
116+             Some ( id)  => return  Err ( InvalidIdentifier ( id) ) , 
117+             None  => return  Err ( NotEnoughItems ) , 
118+         } 
119+ 
120+         let  start_address = u64:: from_le_bytes ( [ 
121+             iter. next ( ) . ok_or ( NotEnoughItems ) ?, 
122+             iter. next ( ) . ok_or ( NotEnoughItems ) ?, 
123+             iter. next ( ) . ok_or ( NotEnoughItems ) ?, 
124+             iter. next ( ) . ok_or ( NotEnoughItems ) ?, 
125+             iter. next ( ) . ok_or ( NotEnoughItems ) ?, 
126+             iter. next ( ) . ok_or ( NotEnoughItems ) ?, 
127+             iter. next ( ) . ok_or ( NotEnoughItems ) ?, 
128+             iter. next ( ) . ok_or ( NotEnoughItems ) ?, 
129+         ] ) ; 
130+ 
131+         let  length = u64:: from_le_bytes ( [ 
132+             iter. next ( ) . ok_or ( NotEnoughItems ) ?, 
133+             iter. next ( ) . ok_or ( NotEnoughItems ) ?, 
134+             iter. next ( ) . ok_or ( NotEnoughItems ) ?, 
135+             iter. next ( ) . ok_or ( NotEnoughItems ) ?, 
136+             iter. next ( ) . ok_or ( NotEnoughItems ) ?, 
137+             iter. next ( ) . ok_or ( NotEnoughItems ) ?, 
138+             iter. next ( ) . ok_or ( NotEnoughItems ) ?, 
139+             iter. next ( ) . ok_or ( NotEnoughItems ) ?, 
140+         ] ) ; 
141+ 
142+         if  length > SIZE  as  u64  { 
143+             return  Err ( LengthTooBig ( length) ) ; 
144+         } 
145+ 
146+         // This call panics if length > SIZE 
147+         // and `iter` does indeed contain more than SIZE items, 
148+         // but we've just covered that case 
149+         let  data = ArrayVec :: from_iter ( iter. take ( length as  usize ) ) ; 
150+ 
151+         Ok ( Self  { 
152+             start_address, 
153+             data, 
154+         } ) 
155+     } 
106156} 
107157
108158#[ cfg( feature = "std" ) ]  
@@ -134,42 +184,7 @@ impl<'a, const SIZE: usize> FromIterator<&'a u8> for ArrayMemoryRegion<SIZE> {
134184
135185impl < const  SIZE :  usize >  FromIterator < u8 >  for  ArrayMemoryRegion < SIZE >  { 
136186    fn  from_iter < T :  IntoIterator < Item  = u8 > > ( iter :  T )  -> Self  { 
137-         let  mut  iter = iter. into_iter ( ) ; 
138- 
139-         assert_eq ! ( 
140-             iter. next( ) . unwrap( ) , 
141-             MEMORY_REGION_IDENTIFIER , 
142-             "The given iterator is not for a memory region" 
143-         ) ; 
144- 
145-         let  start_address = u64:: from_le_bytes ( [ 
146-             iter. next ( ) . unwrap ( ) , 
147-             iter. next ( ) . unwrap ( ) , 
148-             iter. next ( ) . unwrap ( ) , 
149-             iter. next ( ) . unwrap ( ) , 
150-             iter. next ( ) . unwrap ( ) , 
151-             iter. next ( ) . unwrap ( ) , 
152-             iter. next ( ) . unwrap ( ) , 
153-             iter. next ( ) . unwrap ( ) , 
154-         ] ) ; 
155- 
156-         let  length = u64:: from_le_bytes ( [ 
157-             iter. next ( ) . unwrap ( ) , 
158-             iter. next ( ) . unwrap ( ) , 
159-             iter. next ( ) . unwrap ( ) , 
160-             iter. next ( ) . unwrap ( ) , 
161-             iter. next ( ) . unwrap ( ) , 
162-             iter. next ( ) . unwrap ( ) , 
163-             iter. next ( ) . unwrap ( ) , 
164-             iter. next ( ) . unwrap ( ) , 
165-         ] ) ; 
166- 
167-         let  data = ArrayVec :: from_iter ( iter. take ( length as  usize ) ) ; 
168- 
169-         Self  { 
170-             start_address, 
171-             data, 
172-         } 
187+         Self :: try_from_iter ( iter) . unwrap ( ) 
173188    } 
174189} 
175190
@@ -234,6 +249,49 @@ impl VecMemoryRegion {
234249
235250        self . data . as_mut_ptr ( ) . copy_from ( data_ptr,  data_len) ; 
236251    } 
252+ 
253+     /// Try to build a [VecMemoryRegion] from an [IntoIterator<Item = u8>] 
254+      pub  fn  try_from_iter < I :  IntoIterator < Item  = u8 > > ( 
255+         iter :  I , 
256+     )  -> Result < Self ,  MemoryRegionFromIterError >  { 
257+         use  MemoryRegionFromIterError :: * ; 
258+         let  mut  iter = iter. into_iter ( ) ; 
259+ 
260+         match  iter. next ( )  { 
261+             Some ( MEMORY_REGION_IDENTIFIER )  => { } 
262+             Some ( id)  => return  Err ( InvalidIdentifier ( id) ) , 
263+             None  => return  Err ( NotEnoughItems ) , 
264+         } 
265+ 
266+         let  start_address = u64:: from_le_bytes ( [ 
267+             iter. next ( ) . ok_or ( NotEnoughItems ) ?, 
268+             iter. next ( ) . ok_or ( NotEnoughItems ) ?, 
269+             iter. next ( ) . ok_or ( NotEnoughItems ) ?, 
270+             iter. next ( ) . ok_or ( NotEnoughItems ) ?, 
271+             iter. next ( ) . ok_or ( NotEnoughItems ) ?, 
272+             iter. next ( ) . ok_or ( NotEnoughItems ) ?, 
273+             iter. next ( ) . ok_or ( NotEnoughItems ) ?, 
274+             iter. next ( ) . ok_or ( NotEnoughItems ) ?, 
275+         ] ) ; 
276+ 
277+         let  length = u64:: from_le_bytes ( [ 
278+             iter. next ( ) . ok_or ( NotEnoughItems ) ?, 
279+             iter. next ( ) . ok_or ( NotEnoughItems ) ?, 
280+             iter. next ( ) . ok_or ( NotEnoughItems ) ?, 
281+             iter. next ( ) . ok_or ( NotEnoughItems ) ?, 
282+             iter. next ( ) . ok_or ( NotEnoughItems ) ?, 
283+             iter. next ( ) . ok_or ( NotEnoughItems ) ?, 
284+             iter. next ( ) . ok_or ( NotEnoughItems ) ?, 
285+             iter. next ( ) . ok_or ( NotEnoughItems ) ?, 
286+         ] ) ; 
287+ 
288+         let  data = Vec :: from_iter ( iter. take ( length as  usize ) ) ; 
289+ 
290+         Ok ( Self  { 
291+             start_address, 
292+             data, 
293+         } ) 
294+     } 
237295} 
238296
239297#[ cfg( feature = "std" ) ]  
@@ -267,42 +325,7 @@ impl<'a> FromIterator<&'a u8> for VecMemoryRegion {
267325#[ cfg( feature = "std" ) ]  
268326impl  FromIterator < u8 >  for  VecMemoryRegion  { 
269327    fn  from_iter < T :  IntoIterator < Item  = u8 > > ( iter :  T )  -> Self  { 
270-         let  mut  iter = iter. into_iter ( ) ; 
271- 
272-         assert_eq ! ( 
273-             iter. next( ) . unwrap( ) , 
274-             MEMORY_REGION_IDENTIFIER , 
275-             "The given iterator is not for a memory region" 
276-         ) ; 
277- 
278-         let  start_address = u64:: from_le_bytes ( [ 
279-             iter. next ( ) . unwrap ( ) , 
280-             iter. next ( ) . unwrap ( ) , 
281-             iter. next ( ) . unwrap ( ) , 
282-             iter. next ( ) . unwrap ( ) , 
283-             iter. next ( ) . unwrap ( ) , 
284-             iter. next ( ) . unwrap ( ) , 
285-             iter. next ( ) . unwrap ( ) , 
286-             iter. next ( ) . unwrap ( ) , 
287-         ] ) ; 
288- 
289-         let  length = u64:: from_le_bytes ( [ 
290-             iter. next ( ) . unwrap ( ) , 
291-             iter. next ( ) . unwrap ( ) , 
292-             iter. next ( ) . unwrap ( ) , 
293-             iter. next ( ) . unwrap ( ) , 
294-             iter. next ( ) . unwrap ( ) , 
295-             iter. next ( ) . unwrap ( ) , 
296-             iter. next ( ) . unwrap ( ) , 
297-             iter. next ( ) . unwrap ( ) , 
298-         ] ) ; 
299- 
300-         let  data = Vec :: from_iter ( iter. take ( length as  usize ) ) ; 
301- 
302-         Self  { 
303-             start_address, 
304-             data, 
305-         } 
328+         Self :: try_from_iter ( iter) . unwrap ( ) 
306329    } 
307330} 
308331
@@ -433,6 +456,32 @@ impl<'a> Iterator for MemoryRegionIterator<'a> {
433456
434457impl < ' a >  ExactSizeIterator  for  MemoryRegionIterator < ' a >  { } 
435458
459+ #[ derive( Debug ) ]  
460+ /// Specifies what went wrong building a [MemoryRegion] from an iterator 
461+ pub  enum  MemoryRegionFromIterError  { 
462+     /// The given iterator is not for a memory region. 
463+      /// First item from iterator yielded invalid identifier. Expected [MEMORY_REGION_IDENTIFIER] 
464+      InvalidIdentifier ( u8 ) , 
465+     /// Iterator specified length too big for declared region 
466+      LengthTooBig ( u64 ) , 
467+     /// Iterator did not yield enough items to build memory region 
468+      NotEnoughItems , 
469+ } 
470+ 
471+ impl  core:: fmt:: Display  for  MemoryRegionFromIterError  { 
472+     fn  fmt ( & self ,  f :  & mut  core:: fmt:: Formatter < ' _ > )  -> core:: fmt:: Result  { 
473+         use  MemoryRegionFromIterError :: * ; 
474+         match  self  { 
475+             InvalidIdentifier ( id)  => write ! ( f,  "Iterator is not for a memory region. Started with {id}, expected {MEMORY_REGION_IDENTIFIER}" ) , 
476+             LengthTooBig ( len)  => write ! ( f,  "Iterator specified length too big for declared region: {len}" ) , 
477+             NotEnoughItems  => write ! ( f,  "Iterator did not yield enough items to build memory region" ) , 
478+         } 
479+     } 
480+ } 
481+ 
482+ #[ cfg( feature = "std" ) ]  
483+ impl  std:: error:: Error  for  MemoryRegionFromIterError  { } 
484+ 
436485#[ cfg( test) ]  
437486mod  tests { 
438487    use  super :: * ; 
0 commit comments