@@ -47,7 +47,7 @@ use crate::serialization::SerializationError;
4747/// let vec: Vec<u32> = v.into_vec();
4848/// # assert_eq!(vec, vec![2, 3, 5, 7, 11]);
4949/// ```
50- ///
50+ ///
5151/// `Bounded` also re-implements some slice methods with different return
5252/// types, to avoid redundant unwraps:
5353/// ```
@@ -64,16 +64,6 @@ use crate::serialization::SerializationError;
6464/// assert_eq!(rest, &[8, 9]);
6565/// ```
6666///
67- /// **Push behavior:**
68- /// `push` returns an error if it would exceed `MAX` length:
69- /// ```
70- /// # use zebra_chain::serialization::{Bounded, SerializationError};
71- /// #
72- /// # let mut v: Bounded<u32, 1, 2> = vec![1].try_into().unwrap();
73- /// assert!(v.push(2).is_ok());
74- /// assert!(v.push(3).is_err());
75- /// ```
76- ///
7767/// Unlike `Vec`, `first()` and `split_first()` never panic because the
7868/// collection always contains at least `MIN` elements.
7969#[ derive( Clone , Debug , PartialEq , Eq , PartialOrd , Ord , Serialize , Deserialize ) ]
@@ -234,17 +224,6 @@ impl<T, const MIN: usize, const MAX: usize> Bounded<T, MIN, MAX> {
234224 & mut self . inner [ 0 ]
235225 }
236226
237- /// Attempts to append an element to the back of the collection.
238- ///
239- /// Returns an error if appending the element would exceed the maximum length `MAX`.
240- pub fn push ( & mut self , element : T ) -> Result < ( ) , SerializationError > {
241- if self . inner . len ( ) >= MAX {
242- return Err ( SerializationError :: Parse ( "too many elements" ) ) ;
243- }
244- self . inner . push ( element) ;
245- Ok ( ( ) )
246- }
247-
248227 /// Returns the first and all the rest of the elements of the vector.
249228 ///
250229 /// Unlike `Vec` or slice, `Bounded` always has a first element.
@@ -253,188 +232,38 @@ impl<T, const MIN: usize, const MAX: usize> Bounded<T, MIN, MAX> {
253232 }
254233}
255234
256- /// A `Vec<T>` wrapper that ensures there is at least one `T` in the vector.
235+ /// A `Vec<T>` wrapper that guarantees there is **at least one element** in the vector.
236+ ///
237+ /// This is a specialized version of `Bounded<T, 1, usize::MAX>`, and can be used exactly like `Bounded`.
238+ /// In addition to the functionality of `Bounded`, it provides four convenience methods: `push`, `append`, `extend`, and `from_one`.
257239///
258- /// You can initialize `AtLeastOne` using :
240+ /// You can initialize and use `AtLeastOne` just like a `Bounded<T, 1, usize::MAX>` :
259241/// ```
260242/// # use zebra_chain::serialization::{AtLeastOne, SerializationError};
261243/// # use std::convert::{TryFrom, TryInto};
262244/// #
245+ /// // Initialize with one element
263246/// let v: AtLeastOne<u32> = vec![42].try_into()?;
264- /// assert_eq!(v.as_slice(), [42]);
265- ///
266- /// let v: AtLeastOne<u32> = vec![42].as_slice().try_into()?;
267- /// assert_eq!(v.as_slice(), [42]);
268- ///
269- /// let v: AtLeastOne<u32> = [42].try_into()?;
270- /// assert_eq!(v.as_slice(), [42]);
271- ///
272- /// let v = AtLeastOne::<u32>::try_from(&[42])?;
273- /// assert_eq!(v.as_slice(), [42]);
274- /// #
275- /// # Ok::<(), SerializationError>(())
276- /// ```
277- ///
278- /// And access the inner vector via [deref coercion](https://doc.rust-lang.org/std/ops/trait.Deref.html#more-on-deref-coercion),
279- /// an explicit conversion, or as a slice:
280- /// ```
281- /// # use zebra_chain::serialization::AtLeastOne;
282- /// # use std::convert::TryInto;
283- /// #
284- /// # let v: AtLeastOne<u32> = vec![42].try_into().unwrap();
285- /// #
286- /// let first = v.iter().next().expect("AtLeastOne always has a first element");
287- /// assert_eq!(*first, 42);
247+ /// assert_eq!(v.as_slice(), &[42]);
288248///
289- /// let s = v.as_slice();
290- /// #
291- /// # assert_eq!(s, [42]);
249+ /// // Add elements using `push`, `append`, and `extend`
250+ /// let mut v: AtLeastOne<u32> = vec![42].try_into()?;
251+ /// v.push(43);
252+ /// assert_eq!(v.as_slice(), &[42, 43]);
292253///
293- /// let mut m = v.into_vec() ;
294- /// #
295- /// # assert_eq!(m .as_slice(), [42]);
254+ /// let mut other = vec![44, 45] ;
255+ /// v.append(&mut other);
256+ /// assert_eq!(v .as_slice(), & [42, 43, 44, 45 ]);
296257///
297- /// ```
258+ /// v.extend(vec![46, 47]);
259+ /// assert_eq!(v.as_slice(), &[42, 43, 44, 45, 46, 47]);
298260///
299- /// `AtLeastOne` also re-implements some slice methods with different return
300- /// types, to avoid redundant unwraps:
301- /// ```
302- /// # use zebra_chain::serialization::AtLeastOne;
303- /// # use std::convert::TryInto;
304- /// #
305- /// # let v: AtLeastOne<u32> = vec![42].try_into().unwrap();
306- /// #
307- /// let first = v.first();
308- /// assert_eq!(*first, 42);
309- ///
310- /// let (first, rest) = v.split_first();
311- /// assert_eq!(*first, 42);
312- /// assert!(rest.is_empty());
261+ /// // Initialize using `from_one`:
262+ /// let v: AtLeastOne<u32> = AtLeastOne::from_one(42);
263+ /// assert_eq!(v.as_slice(), &[42]);
264+ /// # Ok::<(), SerializationError>(())
313265/// ```
314- #[ derive( Clone , Debug , PartialEq , Eq , PartialOrd , Ord , Serialize , Deserialize ) ]
315- pub struct AtLeastOne < T > {
316- /// The inner vector, which must have at least one element.
317- ///
318- /// `inner` is private, so that it can't be modified in ways that break the
319- /// type constraint.
320- inner : Vec < T > ,
321- }
322-
323- // CORRECTNESS
324- //
325- // All conversions to `AtLeastOne<T>` must go through `TryFrom<Vec<T>>`,
326- // so that the type constraint is satisfied.
327-
328- impl < T > TryFrom < Vec < T > > for AtLeastOne < T > {
329- type Error = SerializationError ;
330-
331- fn try_from ( vec : Vec < T > ) -> Result < Self , Self :: Error > {
332- if vec. is_empty ( ) {
333- Err ( SerializationError :: Parse ( "expected at least one item" ) )
334- } else {
335- Ok ( AtLeastOne { inner : vec } )
336- }
337- }
338- }
339-
340- impl < T > TryFrom < & Vec < T > > for AtLeastOne < T >
341- where
342- T : Clone ,
343- {
344- type Error = SerializationError ;
345-
346- fn try_from ( vec : & Vec < T > ) -> Result < Self , Self :: Error > {
347- if vec. is_empty ( ) {
348- Err ( SerializationError :: Parse ( "expected at least one item" ) )
349- } else {
350- Ok ( AtLeastOne {
351- inner : vec. to_vec ( ) ,
352- } )
353- }
354- }
355- }
356-
357- impl < T > TryFrom < & [ T ] > for AtLeastOne < T >
358- where
359- T : Clone ,
360- {
361- type Error = SerializationError ;
362-
363- fn try_from ( slice : & [ T ] ) -> Result < Self , Self :: Error > {
364- slice. to_vec ( ) . try_into ( )
365- }
366- }
367-
368- // TODO:
369- // - reject [T; 0] at compile time and impl From instead?
370- impl < T , const N : usize > TryFrom < [ T ; N ] > for AtLeastOne < T >
371- where
372- T : Clone ,
373- {
374- type Error = SerializationError ;
375-
376- fn try_from ( slice : [ T ; N ] ) -> Result < Self , Self :: Error > {
377- slice. to_vec ( ) . try_into ( )
378- }
379- }
380-
381- // TODO:
382- // - reject [T; 0] at compile time and impl From instead?
383- // - remove when std is updated so that `TryFrom<&U>` is always implemented when
384- // `TryFrom<U>`
385- impl < T , const N : usize > TryFrom < & [ T ; N ] > for AtLeastOne < T >
386- where
387- T : Clone ,
388- {
389- type Error = SerializationError ;
390-
391- fn try_from ( slice : & [ T ; N ] ) -> Result < Self , Self :: Error > {
392- slice. to_vec ( ) . try_into ( )
393- }
394- }
395-
396- // Deref and AsRef (but not DerefMut or AsMut, because that could break the constraint)
397-
398- impl < T > Deref for AtLeastOne < T > {
399- type Target = Vec < T > ;
400-
401- fn deref ( & self ) -> & Self :: Target {
402- & self . inner
403- }
404- }
405-
406- impl < T > AsRef < [ T ] > for AtLeastOne < T > {
407- fn as_ref ( & self ) -> & [ T ] {
408- self . inner . as_ref ( )
409- }
410- }
411-
412- // Extracting one or more items
413-
414- impl < T > From < AtLeastOne < T > > for Vec < T > {
415- fn from ( vec1 : AtLeastOne < T > ) -> Self {
416- vec1. inner
417- }
418- }
419-
420- // `IntoIterator` for `T` and `&mut T`, because iterators can't remove items
421-
422- impl < T > IntoIterator for AtLeastOne < T > {
423- type Item = T ;
424-
425- type IntoIter = std:: vec:: IntoIter < T > ;
426-
427- fn into_iter ( self ) -> std:: vec:: IntoIter < T > {
428- self . inner . into_iter ( )
429- }
430- }
431-
432- impl < T > AtLeastOne < T > {
433- /// Returns an iterator that allows modifying each value.
434- pub fn iter_mut ( & mut self ) -> std:: slice:: IterMut < ' _ , T > {
435- self . inner . iter_mut ( )
436- }
437- }
266+ pub type AtLeastOne < T > = Bounded < T , 1 , { usize:: MAX } > ;
438267
439268impl < T > AtLeastOne < T > {
440269 /// Returns a new `AtLeastOne`, containing a single `item`.
@@ -446,48 +275,31 @@ impl<T> AtLeastOne<T> {
446275 AtLeastOne { inner : vec ! [ item] }
447276 }
448277
449- /// Returns a reference to the inner vector.
450- pub fn as_vec ( & self ) -> & Vec < T > {
451- & self . inner
452- }
453-
454- /// Converts `self` into a vector without clones or allocation.
455- ///
456- /// The resulting vector can be converted back into `AtLeastOne` via `try_into`.
457- pub fn into_vec ( self ) -> Vec < T > {
458- self . inner
459- }
460-
461- /// Returns the first element.
278+ /// Appends an element to the back of the collection.
462279 ///
463- /// Unlike `Vec` or slice, `AtLeastOne` always has a first element.
464- pub fn first ( & self ) -> & T {
465- & self . inner [ 0 ]
280+ /// This does not violate the `AtLeastOne` constraint since the collection
281+ /// always has at least one element.
282+ pub fn push ( & mut self , element : T ) {
283+ self . inner . push ( element) ;
466284 }
467285
468- /// Returns a mutable reference to the first element .
286+ /// Appends the elements of another collection .
469287 ///
470- /// Unlike `Vec` or slice, `AtLeastOne` always has a first element.
471- pub fn first_mut ( & mut self ) -> & mut T {
472- & mut self . inner [ 0 ]
473- }
474-
475- /// Appends an element to the back of the collection.
476- pub fn push ( & mut self , element : T ) {
477- self . inner . push ( element) ;
288+ /// This does not violate the `AtLeastOne` constraint since the collection
289+ /// always has at least one element.
290+ pub fn append ( & mut self , other : & mut Vec < T > ) {
291+ self . inner . append ( other) ;
478292 }
479293
480- /// Returns the first and all the rest of the elements of the vector .
294+ /// Extends the collection with the elements of an iterator .
481295 ///
482- /// Unlike `Vec` or slice, `AtLeastOne` always has a first element.
483- pub fn split_first ( & self ) -> ( & T , & [ T ] ) {
484- ( & self . inner [ 0 ] , & self . inner [ 1 ..] )
296+ /// This does not violate the `AtLeastOne` constraint since the collection
297+ /// always has at least one element.
298+ pub fn extend < I : IntoIterator < Item = T > > ( & mut self , iter : I ) {
299+ self . inner . extend ( iter) ;
485300 }
486301}
487302
488- // TODO: consider implementing `push`, `append`, and `Extend`,
489- // because adding elements can't break the constraint.
490-
491303/// Create an initialized [`AtLeastOne`] instance.
492304///
493305/// This macro is similar to the [`vec!`][`std::vec!`] macro, but doesn't support creating an empty
0 commit comments