diff --git a/hybrid-array/CHANGELOG.md b/hybrid-array/CHANGELOG.md index 1918effd..59df6f04 100644 --- a/hybrid-array/CHANGELOG.md +++ b/hybrid-array/CHANGELOG.md @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Pending - Added `serde` feature - implements `Serialize` and `Deserialize` for `Array` +- Added `ArrayExt::try_from_fn` ## 0.1.0 (2022-05-07) - Initial release diff --git a/hybrid-array/src/lib.rs b/hybrid-array/src/lib.rs index bc403fd0..1385a7eb 100644 --- a/hybrid-array/src/lib.rs +++ b/hybrid-array/src/lib.rs @@ -576,17 +576,23 @@ pub trait ArrayOps: /// Extension trait with helper functions for core arrays. pub trait ArrayExt: Sized { - /// Create array using the given callback function for each element. - fn from_fn(cb: F) -> Self - where - F: FnMut(usize) -> T; - /// Try to create an array using the given callback function for each element. Returns an error /// if any one of the calls errors fn try_from_fn(cb: F) -> Result where F: FnMut(usize) -> Result; + /// Create array using the given callback function for each element. + fn from_fn(mut cb: F) -> Self + where + F: FnMut(usize) -> T, + { + // Turn the ordinary callback into a Result callback that always returns Ok + let wrapped_cb = |x| Result::::Ok(cb(x)); + // Now use the try_from version of this method + Self::try_from_fn(wrapped_cb).unwrap() + } + /// Create array from a slice, returning [`TryFromSliceError`] if the slice /// length does not match the array length. fn from_slice(slice: &[T]) -> Result @@ -595,6 +601,9 @@ pub trait ArrayExt: Sized { } impl ArrayExt for [T; N] { + // TODO: Eventually remove this and just use the default implementation. It's still + // here because the current Self::try_from_fn might be doing multiple passes over the data, + // depending on optimizations. Thus, this may be faster. fn from_fn(mut cb: F) -> Self where F: FnMut(usize) -> T, @@ -628,8 +637,8 @@ impl ArrayExt for [T; N] { Ok(val) => { elem.write(val); } - Err(e) => { - err_info = Some((idx, e)); + Err(err) => { + err_info = Some((idx, err)); } } } @@ -646,7 +655,7 @@ impl ArrayExt for [T; N] { // If we've made it this far, all the elements have been written. Convert the uninitialized // array to an initialized array // TODO: Replace this map with MaybeUninit::array_assume_init() once it stabilizes - let arr = arr.map(|elem: MaybeUninit| unsafe { elem.assume_init() }); + let arr = arr.map(|v: MaybeUninit| unsafe { v.assume_init() }); Ok(arr) }