-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Provide TryFrom<&[T]>
implementation for &[[T; N]]
#105316
Conversation
The `TryFrom<&[T]>` implementation for `<&[[T; N]]>` allows converting a slice into a slice of N-element chunks while asserting that the slice is evenly divided into those chunks. This is `[T]::as_chunks` but makes it more concise to check that check that there's no reminder. For example, something like: let (chunks, remainder) = slice.as_chunks::<N>(); if !remainder.is_empty() { return Err(SomeError); } becomes: let chunks = <&[[T; N]]>::try_from(slice).map_err(|_| SomeError)?;
The job Click to see the possible cause of the failure (guessed by this bot)
|
A trait implementation such as this will be insta-stable, and needs a fcp. |
By FCP I’m assuming you mean final comment period. How would I trigger that for this change? Or do you mean this needs to wait for the slice_as_chunks’s FCP to be considered? |
You make this its own feature name that this PR would make stable, and it's up to someone from T-libs-api to decide whether to kick off an FCP to add this. |
Alternatively, this is the inverse of (Sadly, the obvious antonym, |
Either works for me so I’m happy to wait for reviewer to decide which path (TryFrom or method) is preferred. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The motivation mentions:
let chunks = <&[[T; N]]>::try_from(slice).map_err(|_| SomeError)?;
I think that use case is covered well enough already by:
let (chunks, []) = slice.as_chunks::<N>() else {return Err(SomeError)};
TryFrom is still more compact and works better with method call fn u64_chunks(bytes: &[u8]) -> Result<&[[u8; u64]]> {
bytes.try_into().map_err(|_| SomeError)
}
// vs
fn u64_chunks(bytes: &[u8]) -> Result<&[[u8; u64]]> {
let (chunks, []) = bytes.as_chunks() else { return Err(SomeError) };
chunks
} let u64s = get_bytes_in_a_vector()
.as_slice()
.try_into::<&[[u8; 8]]>(bytes)
.map_err(|_| SomeError)?
.into_iter()
.map(|chunk| u64::from_le_bytes(*bytes))
.collect::<Vec<_>>();
// vs
let bytes = get_bytes_in_a_vector();
let (chunks, []) = bytes.as_chunks() else { return Err(SomeError.into()); };
let u64s = chunks
.into_iter()
.map(|chunk| u64::from_le_bytes(*bytes))
.collect::<Vec<_>>() let chunks = <&[[_; N]]>::try_from(slice).unwrap();
// or
let chunks = slice.try_into::<&[[_; N]]>().unwrap();
// vs
let (chunks, []) = slice.as_chunks::<N>() else { unreachable!() }; so I’d still love to have it even with let-else alternative. |
I really liked this structure that dtolney brought up in rust-lang#105316, so wanted to put it in the docs to help others use it.
…r=the8472 Another `as_chunks` example I really liked this structure that dtolney brought up in rust-lang#105316, so wanted to put it in the docs to help others use it.
Looking at this again, I'm still not sold that this API carries its weight. I think the best chance for you to get this moving would be follow https://std-dev-guide.rust-lang.org/feature-lifecycle/api-change-proposals.html and open a convincing API change proposal in https://github.com/rust-lang/libs-team, to give someone else on the team (not me) a chance to second it if they like the idea. |
TryFrom<&[T]>
implementation for <&[[T; N]]>
TryFrom<&[T]>
implementation for &[[T; N]]
@rustbot label -S-waiting-on-author +S-waiting-on-ACP |
Since this is insta-stable, it probably needs a resolution to the "what to do for |
The
TryFrom<&[T]>
implementation for&[[T; N]]
allows convertinga slice into a slice of N-element chunks while asserting that the
slice is evenly divided into those chunks. This is
[T]::as_chunks
but makes it more concise to check that check that there's no
reminder. For example, something like:
becomes:
ACP: rust-lang/libs-team#201