Skip to content

Utilities for working with uninitialized arrays

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT
Notifications You must be signed in to change notification settings

cameron1024/unarray

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

17 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Unarray

Docs badge crates badge github badge license badge

Utilities for working with uninitialized arrays

  • No dependencies
  • #[no_std]
  • No panics (all APIs return Result or Option)

This crate provides a few sets of APIs:

uninit_buf and mark_initialized

These are a pair of functions which are generally used as follows:

  • stack-allocate an uninitialized array with uninit_buf
  • initialize each element
  • unsafely convert it to an initialized array with mark_initialized

For example:

use unarray::*;

fn main() {
  let mut buffer = uninit_buf::<i32; 10>();

  for slot in &mut buffer {
    slot.write(123);
  }

  let array = unsafe { mark_initialized(buffer) };

  assert_eq!(array, [123; 10]);
}

This is simple to understand, but still requires unsafe, which is hard to justify in many cases

build_array_*

Functions to build arrays from a length and a function that maps from index -> value:

let even_numbers = build_array(|i| i * 2);  // const generic length parameter inferred
assert_eq!(even_numbers, [0, 2, 4]);

let numbers = build_array_option::<usize, 3>(|i| 3.checked_sub(i));
assert_eq!(numbers, Some([3, 2, 1]));

let numbers = build_array_option::<usize, 5>(|i| 3.checked_sub(i));
assert_eq!(numbers, None);  // since a single element failed, the whole operation failed

There is also an equivalent build_array_result for Result-returning functions

Collecting iterators to arrays

It's fairly common to want to collect an iterator into an array, but this is currently tricky in stable Rust, since iterators don't carry compile-time information about their length. Because of this, arrays don't implement FromIterator, which is required for .collect() to work.

Instead, this library provides ArrayFromIter, which does implement FromIterator. This struct can be destructured to get an Option<[T, N]>. If the iterator contained exactly N elements, this is Some(array), otherwise, it is None:

let iter = [1, 2, 3].into_iter();
match iter.collect() {
  ArrayFromIter(Some([a, b, c])) => println!("exactly 3 elements: {a}, {b}, {c}"),
  ArrayFromIter(None) => println!("not 3 elements"),
}

UnarrayArrayExt extension trait

// mapping an array via a `Result`
let strings = ["123", "234"];
let numbers = strings.map_result(|s| s.parse());
assert_eq!(numbers, Ok([123, 234]));

let bad_strings = ["123", "uh oh"];
let result = bad_strings.map_result(|s| s.parse::<i32>());
assert!(result.is_err());  // since one of the element fails, the whole operation fails

There is also map_option for functions which return an Option

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

About

Utilities for working with uninitialized arrays

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages