mirror of
https://github.com/Zenithsiz/dcb.git
synced 2026-02-09 11:48:16 +00:00
Improved slicing and indexing into AsciiStrArr.
Added `TryFrom<&str> for AsciiStrArr<N>`.
This commit is contained in:
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
57
src/ascii_str_arr/slice.rs
Normal file
57
src/ascii_str_arr/slice.rs
Normal 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")
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user