Improved slicing and indexing into AsciiStrArr.

Added `TryFrom<&str> for AsciiStrArr<N>`.
This commit is contained in:
2020-09-18 03:56:14 +01:00
parent cdaf7047f4
commit d66b855ab3
3 changed files with 74 additions and 26 deletions

View File

@@ -2,6 +2,7 @@
// Modules
pub mod error;
pub mod slice;
mod visitor;
// Exports
@@ -19,6 +20,8 @@ pub struct AsciiStrArr<const N: usize> {
chars: [AsciiChar; N],
/// Size
///
/// Invariant: Must be `< N`
len: usize,
}
@@ -38,12 +41,14 @@ impl<const N: usize> AsciiStrArr<N> {
/// Converts this string to a `&[AsciiStr]`
#[must_use]
pub fn as_ascii_str(&self) -> &AsciiStr {
// Note: Cannot panic due to our invariant
<&AsciiStr>::from(&self.chars[..self.len])
}
/// Converts this string to a `&mut [AsciiStr]`
#[must_use]
pub fn as_ascii_str_mut(&mut self) -> &mut AsciiStr {
// Note: Cannot panic due to our invariant
<&mut AsciiStr>::from(&mut self.chars[..self.len])
}
@@ -58,18 +63,6 @@ impl<const N: usize> AsciiStrArr<N> {
pub fn as_str(&self) -> &str {
self.as_ascii_str().as_str()
}
/// Returns the `n`th character
#[must_use]
pub fn get(&self, n: usize) -> Option<&AsciiChar> {
self.chars.get(n)
}
/// Returns the `n`th character mutably
#[must_use]
pub fn get_mut(&mut self, n: usize) -> Option<&mut AsciiChar> {
self.chars.get_mut(n)
}
}
impl<const N: usize> AsRef<AsciiStr> for AsciiStrArr<N> {
@@ -84,20 +77,6 @@ impl<const N: usize> AsMut<AsciiStr> for AsciiStrArr<N> {
}
}
impl<const N: usize> std::ops::Index<usize> for AsciiStrArr<N> {
type Output = AsciiChar;
fn index(&self, idx: usize) -> &Self::Output {
self.get(idx).expect("Invalid index access")
}
}
impl<const N: usize> std::ops::IndexMut<usize> for AsciiStrArr<N> {
fn index_mut(&mut self, idx: usize) -> &mut Self::Output {
self.get_mut(idx).expect("Invalid index access")
}
}
impl<const N: usize> PartialEq for AsciiStrArr<N> {
fn eq(&self, other: &Self) -> bool {
AsciiStr::eq(self.as_ascii_str(), other.as_ascii_str())
@@ -210,3 +189,13 @@ impl<const N: usize> TryFrom<&[u8]> for AsciiStrArr<N> {
Self::try_from(ascii_str).map_err(FromByteStringError::TooLong)
}
}
impl<const N: usize> TryFrom<&str> for AsciiStrArr<N> {
type Error = FromByteStringError<N>;
fn try_from(string: &str) -> Result<Self, Self::Error> {
let ascii_str = AsciiStr::from_ascii(string).map_err(FromByteStringError::NotAscii)?;
Self::try_from(ascii_str).map_err(FromByteStringError::TooLong)
}
}

View File

@@ -0,0 +1,57 @@
//! Slicing operations for [`AsciiStrArr`]
// Imports
use super::AsciiStrArr;
use ascii::AsciiChar;
use std::ops::{Index, IndexMut};
/// Helper trait for slicing a [`AsciiStrArr`]
// Note: Adapted from `std::slice::SliceIndex`
pub trait SliceIndex<I>
where
I: ?Sized,
{
/// Output type for this slicing
type Output: ?Sized;
/// Tries to get the `idx`th element
fn get(&self, idx: I) -> Option<&Self::Output>;
/// Tries to get the `idx`th element mutably
fn get_mut(&mut self, idx: I) -> Option<&mut Self::Output>;
}
impl<I, const N: usize> SliceIndex<I> for AsciiStrArr<N>
where
I: std::slice::SliceIndex<[AsciiChar]>,
{
type Output = <I as std::slice::SliceIndex<[AsciiChar]>>::Output;
fn get(&self, idx: I) -> Option<&Self::Output> {
self.as_ascii_str().as_slice().get(idx)
}
fn get_mut(&mut self, idx: I) -> Option<&mut Self::Output> {
self.as_ascii_str_mut().as_mut_slice().get_mut(idx)
}
}
impl<I, const N: usize> Index<I> for AsciiStrArr<N>
where
Self: SliceIndex<I>,
{
type Output = <Self as SliceIndex<I>>::Output;
fn index(&self, idx: I) -> &Self::Output {
self.get(idx).expect("Invalid index access")
}
}
impl<I, const N: usize> IndexMut<I> for AsciiStrArr<N>
where
Self: SliceIndex<I>,
{
fn index_mut(&mut self, idx: I) -> &mut Self::Output {
self.get_mut(idx).expect("Invalid index access")
}
}

View File

@@ -84,6 +84,8 @@
#![allow(clippy::integer_arithmetic, clippy::integer_division)]
// We prefer using match ergonomic where possible
#![allow(clippy::pattern_type_mismatch)]
// Sometimes the blocks make it easier to invert their order
#![allow(clippy::if_not_else)]
// False positives:
// TODO: Remove them in the future once they are no longer triggered.
// We only slice arrays, which are verified at compile time. This