diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 18:31:44 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 18:31:44 +0000 |
commit | c23a457e72abe608715ac76f076f47dc42af07a5 (patch) | |
tree | 2772049aaf84b5c9d0ed12ec8d86812f7a7904b6 /vendor/kstring/src/stack.rs | |
parent | Releasing progress-linux version 1.73.0+dfsg1-1~progress7.99u1. (diff) | |
download | rustc-c23a457e72abe608715ac76f076f47dc42af07a5.tar.xz rustc-c23a457e72abe608715ac76f076f47dc42af07a5.zip |
Merging upstream version 1.74.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/kstring/src/stack.rs')
-rw-r--r-- | vendor/kstring/src/stack.rs | 457 |
1 files changed, 0 insertions, 457 deletions
diff --git a/vendor/kstring/src/stack.rs b/vendor/kstring/src/stack.rs deleted file mode 100644 index 93e2f0722..000000000 --- a/vendor/kstring/src/stack.rs +++ /dev/null @@ -1,457 +0,0 @@ -use std::fmt; - -pub(crate) type Len = u8; - -/// Fixed-size stack-allocated string -#[derive(Copy, Clone)] -pub struct StackString<const CAPACITY: usize> { - len: Len, - buffer: StrBuffer<CAPACITY>, -} - -impl<const CAPACITY: usize> StackString<CAPACITY> { - pub const CAPACITY: usize = CAPACITY; - pub const EMPTY: Self = Self::empty(); - - const fn empty() -> Self { - Self { - len: 0, - buffer: StrBuffer::empty(), - } - } - - /// Create a `StackString` from a `&str`, if it'll fit within `Self::CAPACITY` - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let s = kstring::StackString::<3>::try_new("foo"); - /// assert_eq!(s.as_deref(), Some("foo")); - /// let s = kstring::StackString::<3>::try_new("foobar"); - /// assert_eq!(s, None); - /// ``` - #[inline] - #[must_use] - pub fn try_new(s: &str) -> Option<Self> { - let len = s.as_bytes().len(); - if len <= Self::CAPACITY { - #[cfg(feature = "unsafe")] - let stack = { - unsafe { - // SAFETY: We've confirmed `len` is within size - Self::new_unchecked(s) - } - }; - #[cfg(not(feature = "unsafe"))] - let stack = { Self::new(s) }; - Some(stack) - } else { - None - } - } - - /// Create a `StackString` from a `&str` - /// - /// # Panic - /// - /// Calling this function with a string larger than `Self::CAPACITY` will panic - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let s = kstring::StackString::<3>::new("foo"); - /// assert_eq!(s, "foo"); - /// ``` - #[inline] - #[must_use] - pub fn new(s: &str) -> Self { - let len = s.as_bytes().len() as u8; - debug_assert!(Self::CAPACITY <= Len::MAX.into()); - let buffer = StrBuffer::new(s); - Self { len, buffer } - } - - /// Create a `StackString` from a `&str` - /// - /// # Safety - /// - /// Calling this function with a string larger than `Self::CAPACITY` is undefined behavior. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let s = unsafe { - /// // SAFETY: Literal is short-enough - /// kstring::StackString::<3>::new_unchecked("foo") - /// }; - /// assert_eq!(s, "foo"); - /// ``` - #[inline] - #[must_use] - #[cfg(feature = "unsafe")] - pub unsafe fn new_unchecked(s: &str) -> Self { - let len = s.as_bytes().len() as u8; - debug_assert!(Self::CAPACITY <= Len::MAX.into()); - let buffer = StrBuffer::new_unchecked(s); - Self { len, buffer } - } - - /// Extracts a string slice containing the entire `StackString`. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let s = kstring::StackString::<3>::try_new("foo").unwrap(); - /// - /// assert_eq!("foo", s.as_str()); - /// ``` - #[inline] - #[must_use] - pub fn as_str(&self) -> &str { - let len = self.len as usize; - #[cfg(feature = "unsafe")] - unsafe { - // SAFETY: Constructors guarantee that `buffer[..len]` is a `str`, - // and we don't mutate the data afterwards. - self.buffer.as_str_unchecked(len) - } - #[cfg(not(feature = "unsafe"))] - self.buffer.as_str(len) - } - - /// Converts a `StackString` into a mutable string slice. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let mut s = kstring::StackString::<6>::try_new("foobar").unwrap(); - /// let s_mut_str = s.as_mut_str(); - /// - /// s_mut_str.make_ascii_uppercase(); - /// - /// assert_eq!("FOOBAR", s_mut_str); - /// ``` - #[inline] - #[must_use] - pub fn as_mut_str(&mut self) -> &mut str { - let len = self.len as usize; - #[cfg(feature = "unsafe")] - unsafe { - // SAFETY: Constructors guarantee that `buffer[..len]` is a `str`, - // and we don't mutate the data afterwards. - self.buffer.as_mut_str_unchecked(len) - } - #[cfg(not(feature = "unsafe"))] - self.buffer.as_mut_str(len) - } - - /// Returns the length of this `StasckString`, in bytes, not [`char`]s or - /// graphemes. In other words, it might not be what a human considers the - /// length of the string. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let a = kstring::StackString::<3>::try_new("foo").unwrap(); - /// assert_eq!(a.len(), 3); - /// - /// let fancy_f = kstring::StackString::<4>::try_new("ƒoo").unwrap(); - /// assert_eq!(fancy_f.len(), 4); - /// assert_eq!(fancy_f.chars().count(), 3); - /// ``` - #[inline] - #[must_use] - pub fn len(&self) -> usize { - self.len as usize - } - - /// Returns `true` if this `StackString` has a length of zero, and `false` otherwise. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let mut v = kstring::StackString::<20>::EMPTY; - /// assert!(v.is_empty()); - /// - /// let a = kstring::StackString::<3>::try_new("foo").unwrap(); - /// assert!(!a.is_empty()); - /// ``` - #[inline] - #[must_use] - pub fn is_empty(&self) -> bool { - self.len() == 0 - } - - /// Truncates this `StackString`, removing all contents. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let mut s = kstring::StackString::<3>::try_new("foo").unwrap(); - /// - /// s.clear(); - /// - /// assert!(s.is_empty()); - /// assert_eq!(0, s.len()); - /// ``` - #[inline] - pub fn clear(&mut self) { - self.len = 0; - } - - /// Shortens this `StackString` to the specified length. - /// - /// If `new_len` is greater than the string's current length, this has no - /// effect. - /// - /// Note that this method has no effect on the allocated capacity - /// of the string - /// - /// # Panics - /// - /// Panics if `new_len` does not lie on a [`char`] boundary. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let mut s = kstring::StackString::<5>::try_new("hello").unwrap(); - /// - /// s.truncate(2); - /// - /// assert_eq!(s, "he"); - /// ``` - #[inline] - pub fn truncate(&mut self, new_len: usize) { - if new_len <= self.len() { - assert!(self.is_char_boundary(new_len)); - self.len = new_len as u8; - } - } -} - -impl<const CAPACITY: usize> Default for StackString<CAPACITY> { - fn default() -> Self { - Self::empty() - } -} - -impl<const CAPACITY: usize> std::ops::Deref for StackString<CAPACITY> { - type Target = str; - - #[inline] - fn deref(&self) -> &str { - self.as_str() - } -} - -impl<const CAPACITY: usize> Eq for StackString<CAPACITY> {} - -impl<const C1: usize, const C2: usize> PartialEq<StackString<C1>> for StackString<C2> { - #[inline] - fn eq(&self, other: &StackString<C1>) -> bool { - PartialEq::eq(self.as_str(), other.as_str()) - } -} - -impl<const CAPACITY: usize> PartialEq<str> for StackString<CAPACITY> { - #[inline] - fn eq(&self, other: &str) -> bool { - PartialEq::eq(self.as_str(), other) - } -} - -impl<'s, const CAPACITY: usize> PartialEq<&'s str> for StackString<CAPACITY> { - #[inline] - fn eq(&self, other: &&str) -> bool { - PartialEq::eq(self.as_str(), *other) - } -} - -impl<const CAPACITY: usize> PartialEq<String> for StackString<CAPACITY> { - #[inline] - fn eq(&self, other: &String) -> bool { - PartialEq::eq(self.as_str(), other.as_str()) - } -} - -impl<const CAPACITY: usize> Ord for StackString<CAPACITY> { - #[inline] - fn cmp(&self, other: &Self) -> std::cmp::Ordering { - self.as_str().cmp(other.as_str()) - } -} - -impl<const C1: usize, const C2: usize> PartialOrd<StackString<C1>> for StackString<C2> { - #[inline] - fn partial_cmp(&self, other: &StackString<C1>) -> Option<std::cmp::Ordering> { - self.as_str().partial_cmp(other.as_str()) - } -} - -impl<const CAPACITY: usize> PartialOrd<str> for StackString<CAPACITY> { - #[inline] - fn partial_cmp(&self, other: &str) -> Option<std::cmp::Ordering> { - self.as_str().partial_cmp(other) - } -} - -impl<'s, const CAPACITY: usize> PartialOrd<&'s str> for StackString<CAPACITY> { - #[inline] - fn partial_cmp(&self, other: &&str) -> Option<std::cmp::Ordering> { - self.as_str().partial_cmp(other) - } -} - -impl<const CAPACITY: usize> PartialOrd<String> for StackString<CAPACITY> { - #[inline] - fn partial_cmp(&self, other: &String) -> Option<std::cmp::Ordering> { - self.as_str().partial_cmp(other.as_str()) - } -} - -impl<const CAPACITY: usize> std::hash::Hash for StackString<CAPACITY> { - #[inline] - fn hash<H: std::hash::Hasher>(&self, state: &mut H) { - self.as_str().hash(state); - } -} - -impl<const CAPACITY: usize> fmt::Debug for StackString<CAPACITY> { - #[inline] - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Debug::fmt(self.as_str(), f) - } -} - -impl<const CAPACITY: usize> fmt::Display for StackString<CAPACITY> { - #[inline] - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Display::fmt(self.as_str(), f) - } -} - -impl<const CAPACITY: usize> AsRef<str> for StackString<CAPACITY> { - #[inline] - fn as_ref(&self) -> &str { - self.as_str() - } -} - -impl<const CAPACITY: usize> AsRef<[u8]> for StackString<CAPACITY> { - #[inline] - fn as_ref(&self) -> &[u8] { - self.as_bytes() - } -} - -impl<const CAPACITY: usize> AsRef<std::ffi::OsStr> for StackString<CAPACITY> { - #[inline] - fn as_ref(&self) -> &std::ffi::OsStr { - (&**self).as_ref() - } -} - -impl<const CAPACITY: usize> AsRef<std::path::Path> for StackString<CAPACITY> { - #[inline] - fn as_ref(&self) -> &std::path::Path { - std::path::Path::new(self) - } -} - -impl<const CAPACITY: usize> std::borrow::Borrow<str> for StackString<CAPACITY> { - #[inline] - fn borrow(&self) -> &str { - self.as_str() - } -} - -#[derive(Copy, Clone)] -#[repr(transparent)] -pub(crate) struct StrBuffer<const CAPACITY: usize>([u8; CAPACITY]); - -impl<const CAPACITY: usize> StrBuffer<CAPACITY> { - pub(crate) const fn empty() -> Self { - let array = [0; CAPACITY]; - StrBuffer(array) - } - - #[inline] - pub(crate) fn new(s: &str) -> Self { - let len = s.as_bytes().len(); - debug_assert!(len <= CAPACITY); - let mut buffer = Self::default(); - if let Some(buffer) = buffer.0.get_mut(..len) { - buffer.copy_from_slice(s.as_bytes()); - } else { - panic!("`{}` is larger than capacity {}", s, CAPACITY); - } - buffer - } - - #[inline] - #[cfg(not(feature = "unsafe"))] - pub(crate) fn as_str(&self, len: usize) -> &str { - let slice = self.0.get(..len).unwrap(); - std::str::from_utf8(slice).unwrap() - } - - #[inline] - #[cfg(not(feature = "unsafe"))] - pub(crate) fn as_mut_str(&mut self, len: usize) -> &mut str { - let slice = self.0.get_mut(..len).unwrap(); - std::str::from_utf8_mut(slice).unwrap() - } -} - -impl<const CAPACITY: usize> StrBuffer<CAPACITY> { - #[inline] - #[cfg(feature = "unsafe")] - pub(crate) unsafe fn new_unchecked(s: &str) -> Self { - let len = s.as_bytes().len(); - debug_assert!(len <= CAPACITY); - let mut buffer = Self::default(); - buffer - .0 - .get_unchecked_mut(..len) - .copy_from_slice(s.as_bytes()); - buffer - } - - #[inline] - #[cfg(feature = "unsafe")] - pub(crate) unsafe fn as_str_unchecked(&self, len: usize) -> &str { - let slice = self.0.get_unchecked(..len); - std::str::from_utf8_unchecked(slice) - } - - #[inline] - #[cfg(feature = "unsafe")] - pub(crate) unsafe fn as_mut_str_unchecked(&mut self, len: usize) -> &mut str { - let slice = self.0.get_unchecked_mut(..len); - std::str::from_utf8_unchecked_mut(slice) - } -} - -impl<const CAPACITY: usize> Default for StrBuffer<CAPACITY> { - fn default() -> Self { - Self::empty() - } -} |