Merge pull request #533 from newAM/fix-clippy-result-unit-error

Remove allow(clippy::result_unit_err)
This commit is contained in:
Alex Martens 2025-03-28 09:39:03 +00:00 committed by GitHub
commit 64fee10a3b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 67 additions and 39 deletions

View File

@ -44,6 +44,14 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
### Changed ### Changed
- Changed the error type of these methods from `()` to `CapacityError`.
- `String::push_str`
- `String::push`
- `Vec::extend_from_slice`
- `Vec::from_slice`
- `Vec::resize_default`
- `Vec::resize`
- Renamed `FromUtf16Error::DecodeUtf16Error` to `FromUtf16Error::DecodeUtf16`.
- Changed `stable_deref_trait` to a platform-dependent dependency. - Changed `stable_deref_trait` to a platform-dependent dependency.
- Changed `SortedLinkedList::pop` return type from `Result<T, ()>` to `Option<T>` to match `std::vec::pop`. - Changed `SortedLinkedList::pop` return type from `Result<T, ()>` to `Option<T>` to match `std::vec::pop`.
- `Vec::capacity` is no longer a `const` function. - `Vec::capacity` is no longer a `const` function.

View File

@ -233,3 +233,16 @@ mod ufmt;
pub mod _export { pub mod _export {
pub use crate::string::format; pub use crate::string::format;
} }
/// The error type for fallible [`Vec`] and [`String`] methods.
#[derive(Debug)]
#[non_exhaustive]
pub struct CapacityError;
impl core::fmt::Display for CapacityError {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str("insufficient capacity")
}
}
impl core::error::Error for CapacityError {}

View File

@ -12,6 +12,7 @@ use core::{
}; };
use crate::vec::{OwnedVecStorage, Vec, VecInner, VecStorage, ViewVecStorage}; use crate::vec::{OwnedVecStorage, Vec, VecInner, VecStorage, ViewVecStorage};
use crate::CapacityError;
mod drain; mod drain;
pub use drain::Drain; pub use drain::Drain;
@ -24,20 +25,28 @@ pub use drain::Drain;
#[derive(Debug)] #[derive(Debug)]
pub enum FromUtf16Error { pub enum FromUtf16Error {
/// The capacity of the `String` is too small for the given operation. /// The capacity of the `String` is too small for the given operation.
Capacity, Capacity(CapacityError),
/// Error decoding UTF-16. /// Error decoding UTF-16.
DecodeUtf16Error(DecodeUtf16Error), DecodeUtf16(DecodeUtf16Error),
} }
impl fmt::Display for FromUtf16Error { impl fmt::Display for FromUtf16Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self { match self {
Self::Capacity => "insufficient capacity".fmt(f), Self::Capacity(err) => write!(f, "{err}"),
Self::DecodeUtf16Error(e) => write!(f, "invalid UTF-16: {}", e), Self::DecodeUtf16(err) => write!(f, "invalid UTF-16: {err}"),
} }
} }
} }
impl core::error::Error for FromUtf16Error {}
impl From<CapacityError> for FromUtf16Error {
fn from(e: CapacityError) -> Self {
Self::Capacity(e)
}
}
/// Base struct for [`String`] and [`StringView`], generic over the [`VecStorage`]. /// Base struct for [`String`] and [`StringView`], generic over the [`VecStorage`].
/// ///
/// In most cases you should use [`String`] or [`StringView`] directly. Only use this /// In most cases you should use [`String`] or [`StringView`] directly. Only use this
@ -164,10 +173,10 @@ impl<const N: usize> String<N> {
for c in char::decode_utf16(v.iter().cloned()) { for c in char::decode_utf16(v.iter().cloned()) {
match c { match c {
Ok(c) => { Ok(c) => {
s.push(c).map_err(|_| FromUtf16Error::Capacity)?; s.push(c).map_err(|_| CapacityError)?;
} }
Err(err) => { Err(err) => {
return Err(FromUtf16Error::DecodeUtf16Error(err)); return Err(FromUtf16Error::DecodeUtf16(err));
} }
} }
} }
@ -253,7 +262,7 @@ impl<const N: usize> String<N> {
/// assert!(b.len() == 2); /// assert!(b.len() == 2);
/// ///
/// assert_eq!(&[b'a', b'b'], &b[..]); /// assert_eq!(&[b'a', b'b'], &b[..]);
/// # Ok::<(), ()>(()) /// # Ok::<(), heapless::CapacityError>(())
/// ``` /// ```
#[inline] #[inline]
pub fn into_bytes(self) -> Vec<u8, N> { pub fn into_bytes(self) -> Vec<u8, N> {
@ -360,7 +369,7 @@ impl<S: VecStorage<u8> + ?Sized> StringInner<S> {
/// ///
/// let _s = s.as_str(); /// let _s = s.as_str();
/// // s.push('c'); // <- cannot borrow `s` as mutable because it is also borrowed as immutable /// // s.push('c'); // <- cannot borrow `s` as mutable because it is also borrowed as immutable
/// # Ok::<(), ()>(()) /// # Ok::<(), heapless::CapacityError>(())
/// ``` /// ```
#[inline] #[inline]
pub fn as_str(&self) -> &str { pub fn as_str(&self) -> &str {
@ -379,7 +388,7 @@ impl<S: VecStorage<u8> + ?Sized> StringInner<S> {
/// let mut s: String<4> = String::try_from("ab")?; /// let mut s: String<4> = String::try_from("ab")?;
/// let s = s.as_mut_str(); /// let s = s.as_mut_str();
/// s.make_ascii_uppercase(); /// s.make_ascii_uppercase();
/// # Ok::<(), ()>(()) /// # Ok::<(), heapless::CapacityError>(())
/// ``` /// ```
#[inline] #[inline]
pub fn as_mut_str(&mut self) -> &mut str { pub fn as_mut_str(&mut self) -> &mut str {
@ -411,7 +420,7 @@ impl<S: VecStorage<u8> + ?Sized> StringInner<S> {
/// vec.reverse(); /// vec.reverse();
/// } /// }
/// assert_eq!(s, "olleh"); /// assert_eq!(s, "olleh");
/// # Ok::<(), ()>(()) /// # Ok::<(), heapless::CapacityError>(())
/// ``` /// ```
pub unsafe fn as_mut_vec(&mut self) -> &mut VecInner<u8, S> { pub unsafe fn as_mut_vec(&mut self) -> &mut VecInner<u8, S> {
&mut self.vec &mut self.vec
@ -433,11 +442,10 @@ impl<S: VecStorage<u8> + ?Sized> StringInner<S> {
/// assert_eq!("foobar", s); /// assert_eq!("foobar", s);
/// ///
/// assert!(s.push_str("tender").is_err()); /// assert!(s.push_str("tender").is_err());
/// # Ok::<(), ()>(()) /// # Ok::<(), heapless::CapacityError>(())
/// ``` /// ```
#[inline] #[inline]
#[allow(clippy::result_unit_err)] pub fn push_str(&mut self, string: &str) -> Result<(), CapacityError> {
pub fn push_str(&mut self, string: &str) -> Result<(), ()> {
self.vec.extend_from_slice(string.as_bytes()) self.vec.extend_from_slice(string.as_bytes())
} }
@ -476,13 +484,12 @@ impl<S: VecStorage<u8> + ?Sized> StringInner<S> {
/// assert!("abc123" == s.as_str()); /// assert!("abc123" == s.as_str());
/// ///
/// assert_eq!("abc123", s); /// assert_eq!("abc123", s);
/// # Ok::<(), ()>(()) /// # Ok::<(), heapless::CapacityError>(())
/// ``` /// ```
#[inline] #[inline]
#[allow(clippy::result_unit_err)] pub fn push(&mut self, c: char) -> Result<(), CapacityError> {
pub fn push(&mut self, c: char) -> Result<(), ()> {
match c.len_utf8() { match c.len_utf8() {
1 => self.vec.push(c as u8).map_err(|_| {}), 1 => self.vec.push(c as u8).map_err(|_| CapacityError),
_ => self _ => self
.vec .vec
.extend_from_slice(c.encode_utf8(&mut [0; 4]).as_bytes()), .extend_from_slice(c.encode_utf8(&mut [0; 4]).as_bytes()),
@ -513,7 +520,7 @@ impl<S: VecStorage<u8> + ?Sized> StringInner<S> {
/// s.truncate(2); /// s.truncate(2);
/// ///
/// assert_eq!("he", s); /// assert_eq!("he", s);
/// # Ok::<(), ()>(()) /// # Ok::<(), heapless::CapacityError>(())
/// ``` /// ```
#[inline] #[inline]
pub fn truncate(&mut self, new_len: usize) { pub fn truncate(&mut self, new_len: usize) {
@ -541,7 +548,7 @@ impl<S: VecStorage<u8> + ?Sized> StringInner<S> {
/// assert_eq!(s.pop(), Some('f')); /// assert_eq!(s.pop(), Some('f'));
/// ///
/// assert_eq!(s.pop(), None); /// assert_eq!(s.pop(), None);
/// Ok::<(), ()>(()) /// Ok::<(), heapless::CapacityError>(())
/// ``` /// ```
pub fn pop(&mut self) -> Option<char> { pub fn pop(&mut self) -> Option<char> {
let ch = self.chars().next_back()?; let ch = self.chars().next_back()?;
@ -615,7 +622,7 @@ impl<S: VecStorage<u8> + ?Sized> StringInner<S> {
/// assert!(s.is_empty()); /// assert!(s.is_empty());
/// assert_eq!(0, s.len()); /// assert_eq!(0, s.len());
/// assert_eq!(8, s.capacity()); /// assert_eq!(8, s.capacity());
/// Ok::<(), ()>(()) /// Ok::<(), heapless::CapacityError>(())
/// ``` /// ```
#[inline] #[inline]
pub fn clear(&mut self) { pub fn clear(&mut self) {
@ -630,7 +637,8 @@ impl<const N: usize> Default for String<N> {
} }
impl<'a, const N: usize> TryFrom<&'a str> for String<N> { impl<'a, const N: usize> TryFrom<&'a str> for String<N> {
type Error = (); type Error = CapacityError;
fn try_from(s: &'a str) -> Result<Self, Self::Error> { fn try_from(s: &'a str) -> Result<Self, Self::Error> {
let mut new = Self::new(); let mut new = Self::new();
new.push_str(s)?; new.push_str(s)?;
@ -639,7 +647,7 @@ impl<'a, const N: usize> TryFrom<&'a str> for String<N> {
} }
impl<const N: usize> str::FromStr for String<N> { impl<const N: usize> str::FromStr for String<N> {
type Err = (); type Err = CapacityError;
fn from_str(s: &str) -> Result<Self, Self::Err> { fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut new = Self::new(); let mut new = Self::new();
@ -912,7 +920,7 @@ impl_try_from_num!(u64, 20);
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::{String, Vec}; use crate::{CapacityError, String, Vec};
#[test] #[test]
fn static_new() { fn static_new() {
@ -980,7 +988,7 @@ mod tests {
assert!(s.len() == 3); assert!(s.len() == 3);
assert_eq!(s, "123"); assert_eq!(s, "123");
let _: () = String::<2>::try_from("123").unwrap_err(); let _: CapacityError = String::<2>::try_from("123").unwrap_err();
} }
#[test] #[test]
@ -991,7 +999,7 @@ mod tests {
assert!(s.len() == 3); assert!(s.len() == 3);
assert_eq!(s, "123"); assert_eq!(s, "123");
let _: () = String::<2>::from_str("123").unwrap_err(); let _: CapacityError = String::<2>::from_str("123").unwrap_err();
} }
#[test] #[test]

View File

@ -1,18 +1,19 @@
use crate::{ use crate::{
string::StringInner, string::StringInner,
vec::{VecInner, VecStorage}, vec::{VecInner, VecStorage},
CapacityError,
}; };
use ufmt_write::uWrite; use ufmt_write::uWrite;
impl<S: VecStorage<u8> + ?Sized> uWrite for StringInner<S> { impl<S: VecStorage<u8> + ?Sized> uWrite for StringInner<S> {
type Error = (); type Error = CapacityError;
fn write_str(&mut self, s: &str) -> Result<(), Self::Error> { fn write_str(&mut self, s: &str) -> Result<(), Self::Error> {
self.push_str(s) self.push_str(s)
} }
} }
impl<S: VecStorage<u8> + ?Sized> uWrite for VecInner<u8, S> { impl<S: VecStorage<u8> + ?Sized> uWrite for VecInner<u8, S> {
type Error = (); type Error = CapacityError;
fn write_str(&mut self, s: &str) -> Result<(), Self::Error> { fn write_str(&mut self, s: &str) -> Result<(), Self::Error> {
self.extend_from_slice(s.as_bytes()) self.extend_from_slice(s.as_bytes())
} }

View File

@ -11,6 +11,8 @@ use core::{
slice, slice,
}; };
use crate::CapacityError;
mod drain; mod drain;
mod storage { mod storage {
@ -192,8 +194,7 @@ impl<T, const N: usize> Vec<T, N> {
/// let mut v: Vec<u8, 16> = Vec::new(); /// let mut v: Vec<u8, 16> = Vec::new();
/// v.extend_from_slice(&[1, 2, 3]).unwrap(); /// v.extend_from_slice(&[1, 2, 3]).unwrap();
/// ``` /// ```
#[allow(clippy::result_unit_err)] pub fn from_slice(other: &[T]) -> Result<Self, CapacityError>
pub fn from_slice(other: &[T]) -> Result<Self, ()>
where where
T: Clone, T: Clone,
{ {
@ -516,8 +517,7 @@ impl<T, S: VecStorage<T> + ?Sized> VecInner<T, S> {
/// vec.extend_from_slice(&[2, 3, 4]).unwrap(); /// vec.extend_from_slice(&[2, 3, 4]).unwrap();
/// assert_eq!(*vec, [1, 2, 3, 4]); /// assert_eq!(*vec, [1, 2, 3, 4]);
/// ``` /// ```
#[allow(clippy::result_unit_err)] pub fn extend_from_slice(&mut self, other: &[T]) -> Result<(), CapacityError>
pub fn extend_from_slice(&mut self, other: &[T]) -> Result<(), ()>
where where
T: Clone, T: Clone,
{ {
@ -525,13 +525,13 @@ impl<T, S: VecStorage<T> + ?Sized> VecInner<T, S> {
len: &mut usize, len: &mut usize,
buf: &mut [MaybeUninit<T>], buf: &mut [MaybeUninit<T>],
other: &[T], other: &[T],
) -> Result<(), ()> ) -> Result<(), CapacityError>
where where
T: Clone, T: Clone,
{ {
if *len + other.len() > buf.len() { if *len + other.len() > buf.len() {
// won't fit in the `Vec`; don't modify anything and return an error // won't fit in the `Vec`; don't modify anything and return an error
Err(()) Err(CapacityError)
} else { } else {
for elem in other { for elem in other {
unsafe { *buf.get_unchecked_mut(*len) = MaybeUninit::new(elem.clone()) } unsafe { *buf.get_unchecked_mut(*len) = MaybeUninit::new(elem.clone()) }
@ -626,13 +626,12 @@ impl<T, S: VecStorage<T> + ?Sized> VecInner<T, S> {
/// `new_len` is less than len, the Vec is simply truncated. /// `new_len` is less than len, the Vec is simply truncated.
/// ///
/// See also [`resize_default`](Self::resize_default). /// See also [`resize_default`](Self::resize_default).
#[allow(clippy::result_unit_err)] pub fn resize(&mut self, new_len: usize, value: T) -> Result<(), CapacityError>
pub fn resize(&mut self, new_len: usize, value: T) -> Result<(), ()>
where where
T: Clone, T: Clone,
{ {
if new_len > self.capacity() { if new_len > self.capacity() {
return Err(()); return Err(CapacityError);
} }
if new_len > self.len { if new_len > self.len {
@ -653,8 +652,7 @@ impl<T, S: VecStorage<T> + ?Sized> VecInner<T, S> {
/// If `new_len` is less than `len`, the `Vec` is simply truncated. /// If `new_len` is less than `len`, the `Vec` is simply truncated.
/// ///
/// See also [`resize`](Self::resize). /// See also [`resize`](Self::resize).
#[allow(clippy::result_unit_err)] pub fn resize_default(&mut self, new_len: usize) -> Result<(), CapacityError>
pub fn resize_default(&mut self, new_len: usize) -> Result<(), ()>
where where
T: Clone + Default, T: Clone + Default,
{ {
@ -1211,7 +1209,7 @@ impl<T, S: VecStorage<T> + ?Sized> Drop for VecInner<T, S> {
} }
impl<'a, T: Clone, const N: usize> TryFrom<&'a [T]> for Vec<T, N> { impl<'a, T: Clone, const N: usize> TryFrom<&'a [T]> for Vec<T, N> {
type Error = (); type Error = CapacityError;
fn try_from(slice: &'a [T]) -> Result<Self, Self::Error> { fn try_from(slice: &'a [T]) -> Result<Self, Self::Error> {
Self::from_slice(slice) Self::from_slice(slice)