#[doc = crate::_tags!(value mem)]
#[doc = crate::_doc_location!("data/layout/array")]
#[derive(Debug)]
pub struct ArrayFrom<T>(pub T);
#[rustfmt::skip]
#[allow(clippy::len_without_is_empty)]
mod impls {
use crate::{Slice, ArrayFrom};
impl ArrayFrom<u8> {
pub const fn len(self) -> usize { 1 }
pub const fn to_array<const N: usize>(self) -> [u8; N] { Slice::to_array(&[self.0]) }
}
impl<const L: usize> ArrayFrom<[u8; L]> {
pub const fn len(&self) -> usize { L }
pub const fn to_array<const N: usize>(&self) -> [u8; N] { Slice::to_array(&self.0) }
}
impl<const L: usize> ArrayFrom<&[u8; L]> {
pub const fn len(&self) -> usize { L }
pub const fn to_array<const N: usize>(&self) -> [u8; N] { Slice::to_array(self.0) }
}
impl ArrayFrom<&[u8]> {
pub const fn len(&self) -> usize { self.0.len() }
pub const fn to_array<const N: usize>(&self) -> [u8; N] { Slice::to_array(self.0) }
}
impl ArrayFrom<&[&[u8]]> {
pub const fn len(&self) -> usize {
let parts = self.0; let mut sum = 0; let mut i = 0;
while i < parts.len() { sum += parts[i].len(); i += 1; }
sum
}
pub const fn to_array<const N: usize>(&self) -> [u8; N] {
let (mut buf, mut pos, parts, mut i) = ([0; N], 0, self.0, 0);
while i < parts.len() {
let part = parts[i];
Slice::copy_array_at(&mut buf, part, pos);
pos += part.len();
i += 1;
}
assert!(pos == N);
buf
}
}
impl ArrayFrom<&str> {
pub const fn len(&self) -> usize { self.0.len() }
pub const fn to_array<const N: usize>(&self) -> [u8; N] {
Slice::to_array(self.0.as_bytes())
}
}
impl ArrayFrom<&[&str]> {
pub const fn len(&self) -> usize {
let (mut len, mut rem) = (0, self.0);
while let [first, rest @ ..] = rem {
len += first.len();
rem = rest;
}
len
}
pub const fn to_array<const N: usize>(&self) -> [u8; N] {
let (mut buf, mut pos, mut i) = ([0; N], 0, 0);
while i < self.0.len() {
let bytes = self.0[i].as_bytes();
crate::Slice::<u8>::copy_array_at(&mut buf, bytes, pos);
pos += bytes.len();
i += 1;
}
assert!(pos == N);
buf
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn from_u8() {
assert_eq!(ArrayFrom(42u8).to_array::<1>(), [42]);
}
#[test]
fn from_array() {
assert_eq!(ArrayFrom([1, 2, 3]).to_array::<3>(), [1, 2, 3]);
}
#[test]
fn from_array_ref() {
assert_eq!(ArrayFrom(&[1, 2, 3]).to_array::<3>(), [1, 2, 3]);
}
#[test]
fn from_str() {
assert_eq!(ArrayFrom("foo").to_array::<3>(), *b"foo");
}
#[test]
#[should_panic]
fn from_length_mismatch() {
let _ = ArrayFrom(&[1, 2, 3]).to_array::<2>();
}
}