@@ -1005,3 +1005,51 @@ where
10051005 }
10061006 }
10071007}
1008+
1009+ // #[stable(feature = "array_try_from_vec", since = "1.48.0")]
1010+ impl < T , A : Allocator , const N : usize > TryFrom < Vec < T , A > > for [ T ; N ] {
1011+ type Error = Vec < T , A > ;
1012+
1013+ /// Gets the entire contents of the `Vec<T>` as an array,
1014+ /// if its size exactly matches that of the requested array.
1015+ ///
1016+ /// # Examples
1017+ ///
1018+ /// ```
1019+ /// assert_eq!(vec![1, 2, 3].try_into(), Ok([1, 2, 3]));
1020+ /// assert_eq!(<Vec<i32>>::new().try_into(), Ok([]));
1021+ /// ```
1022+ ///
1023+ /// If the length doesn't match, the input comes back in `Err`:
1024+ /// ```
1025+ /// let r: Result<[i32; 4], _> = (0..10).collect::<Vec<_>>().try_into();
1026+ /// assert_eq!(r, Err(vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9]));
1027+ /// ```
1028+ ///
1029+ /// If you're fine with just getting a prefix of the `Vec<T>`,
1030+ /// you can call [`.truncate(N)`](Vec::truncate) first.
1031+ /// ```
1032+ /// let mut v = String::from("hello world").into_bytes();
1033+ /// v.sort();
1034+ /// v.truncate(2);
1035+ /// let [a, b]: [_; 2] = v.try_into().unwrap();
1036+ /// assert_eq!(a, b' ');
1037+ /// assert_eq!(b, b'd');
1038+ /// ```
1039+ fn try_from ( mut vec : Vec < T , A > ) -> Result < [ T ; N ] , Vec < T , A > > {
1040+ if vec. len ( ) != N {
1041+ return Err ( vec) ;
1042+ }
1043+
1044+ // SAFETY: `.set_len(0)` is always sound.
1045+ unsafe { vec. set_len ( 0 ) } ;
1046+
1047+ // SAFETY: A `Vec`'s pointer is always aligned properly, and
1048+ // the alignment the array needs is the same as the items.
1049+ // We checked earlier that we have sufficient items.
1050+ // The items will not double-drop as the `set_len`
1051+ // tells the `Vec` not to also drop them.
1052+ let array = unsafe { ptr:: read ( vec. as_ptr ( ) as * const [ T ; N ] ) } ;
1053+ Ok ( array)
1054+ }
1055+ }
0 commit comments