From 7253d950108c729141239f4add4b3df67a54db31 Mon Sep 17 00:00:00 2001 From: pantonshire Date: Wed, 14 Sep 2022 20:09:25 +0100 Subject: [PATCH] strings: CappedString to FixedString conversion methods This patch adds `CappedString::into_fixed` and `CappedString::into_fixed_max_capacity` to allow for checked conversions from `CappedString` to `FixedString`. --- src/strings/capped.rs | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/strings/capped.rs b/src/strings/capped.rs index 7104df6..2625108 100644 --- a/src/strings/capped.rs +++ b/src/strings/capped.rs @@ -20,6 +20,8 @@ use alloc::{ #[cfg(feature = "std")] use std::borrow::Cow; +use super::fixed::{FixedString, LengthError}; + #[derive(Debug)] pub struct CapacityError; @@ -45,7 +47,11 @@ impl std::error::Error for CapacityError {} /// ``` #[derive(Clone)] pub struct CappedString { + /// The buffer storing the string data. It is an invariant of this type that the first `len` + /// elements of this buffer is initialised, valid UTF-8 string data. buf: [MaybeUninit; N], + + /// The length of the string stored in `buf`. len: u8, } @@ -70,6 +76,10 @@ impl CappedString { Self { buf, len } } + /// Returns the raw buffer and length backing this `CappedString`; the first element of the + /// tuple is the buffer `buf` and the second is the length `len`. The first `len` elements of + /// `buf` (i.e. `&buf[..usize::from(len)]`) is guaranteed to be initialised, valid UTF-8 string + /// data. #[inline] #[must_use] pub const fn into_raw_parts(self) -> ([MaybeUninit; N], u8) { @@ -476,6 +486,24 @@ impl CappedString { pub fn is_empty(&self) -> bool { self.len == 0 } + + #[inline] + pub fn into_fixed(self) -> Result, LengthError> { + let buf: [u8; M] = self + .as_bytes() + .try_into() + .map_err(|_| LengthError)?; + + // SAFETY: + // It is an invariant of `CappedString` that the first `self.len` bytes of `self.buf` is + // valid UTF-8, so the bytes returned by `Self::as_bytes` are valid UTF-8. + unsafe { Ok(FixedString::from_raw_array(buf)) } + } + + #[inline] + pub fn into_fixed_max_capacity(self) -> Result, LengthError> { + self.into_fixed() + } } #[cfg(feature = "alloc")]