Skip to content

Feature request: Conversion from &[[T; N]] to &[GenericArray<T, N>] (and &mut) #145

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
jrose-signal opened this issue Aug 25, 2023 · 10 comments · Fixed by #138
Closed

Feature request: Conversion from &[[T; N]] to &[GenericArray<T, N>] (and &mut) #145

jrose-signal opened this issue Aug 25, 2023 · 10 comments · Fixed by #138

Comments

@jrose-signal
Copy link

jrose-signal commented Aug 25, 2023

APIs like the cipher crate's BlockEncrypt::encrypt_blocks take a slice of GenericArrays. However, if you're starting with a flat &[u8], it's unergonomic to get to the required type. The unstable slice::as_chunks gives you &[[u8; N]], but going from that to &[GenericArray<u8, _>] seems impossible without a pointer cast or transmute. However, that pointer cast or transmute is valid because GenericArray is repr(transparent), and it would be nice™ if the generic-array crate provided that operation as a safe wrapper.

@novacrazy
Copy link
Collaborator

What would be a good name for these methods? GenericArray::chunks_from_slice/GenericArray::chunks_from_slice_mut?

About to commit them, just having a difficult time naming them.

@jrose-signal
Copy link
Author

jrose-signal commented Aug 25, 2023

I was thinking "something similar to whatever the current [T; N] -> GenericArray conversion is called", but that's just From/Into. Which I think could actually be implemented here too, but maybe that's too subtle. To me, chunks_from_slice feels like it's going from a flat list to a chunked one, like slice::as_chunks, but the only thing I can come up with is from_slice_of_arrays and that doesn't carry the implication of producing a slice. 🤷 Yeah, tricky one!

@jrose-signal
Copy link
Author

I also wonder if the reverse operation is valuable enough to add at the same time, even if I personally don't have a use for it right now.

@novacrazy
Copy link
Collaborator

This is the signature for what I have so far:

impl<T, N: ArrayLength> GenericArray<T, N> {
    pub const fn chunks_from_slice(slice: &[T]) -> (&[GenericArray<T, N>], &[T])

and the mutable version.

It's worth noting this will be on the 1.0 branch in #138

I can do the opposite with &[GenericArray<T, N>] to &[T]. That would be easy, though determining name and where to place it is not. We can't define methods directly onto &[T] or &[GenericArray<T, N>]. Using traits would invalidate const-usage as well, but might still be a good place to put versions with simpler names.

@jrose-signal
Copy link
Author

Oh, I was thinking this signature:

impl <T, N: ArrayLength<T>> GenericArray<T, N> {
  fn from_slice_of_arrays(slice: &[[T; N::USIZE]]) -> &[GenericArray<T, N>] { … }
}

except macro-generated cause N::USIZE isn't actually supported there yet. I guess doing the full jump works too, in which case chunks_from_slice seems like an appropriate name to me.

@novacrazy
Copy link
Collaborator

except macro-generated cause N::USIZE isn't actually supported there yet

That was true in pre-1.0, but as of 1.0 we can do:

pub const fn from_chunks<const U: usize>(chunks: &[[T; U]]) -> &[GenericArray<T, N>]
where
    Const<U>: IntoArrayLength<ArrayLength = N>,
{}

I can include both, and hopefully the full 1.0 releases within a week.

@jrose-signal
Copy link
Author

jrose-signal commented Aug 25, 2023

So then there's a naming question for the opposite operation:

pub const fn as_slice_of_arrays<const U: usize>(chunks: &[GenericArray<T, N>]) -> &[[T; U]]
where
    Const<U>: IntoArrayLength<ArrayLength = N>,
{}

Does generic-array have a standard name for the built-in, lang-item fixed-sized arrays?

@novacrazy
Copy link
Collaborator

Does generic-array have a standard name for the built-in, lang-item fixed-sized arrays?

Not really, no.

into_chunks feels somewhat natural as an inverse to from_chunks, but could be confusing to some. "Chunks" being a common term over both &[[T; N]] and &[GenericArray<T, N>] is a tad annoying.

For an inverse of chunks_from_slice, slice_from_chunks works, albeit with the same naming caveats.

At least Rust will prevent them from being used incorrectly.

novacrazy added a commit that referenced this issue Aug 25, 2023
@novacrazy novacrazy mentioned this issue Aug 25, 2023
Merged
2 tasks
@novacrazy
Copy link
Collaborator

Also hopefully it won't take years for the Rust crypto crates to upgrade to GA 1.0. If you absolutely must have these backported, I can look into it sometime.

@jrose-signal
Copy link
Author

No, it's okay, we're currently just going to use the raw cast like slice::as_chunks. Just trying to make things better for the future!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants