From 8bee76b1bc65017dc433c7c2a42eda474ec415cf Mon Sep 17 00:00:00 2001 From: Parker Timmerman Date: Sat, 8 Jun 2024 15:01:36 -0400 Subject: [PATCH] fix: More `PartialEq` impls (#381) * start * fix clippy * some more impls --- compact_str/src/lib.rs | 59 +++++++++++++++++++++++++++++++++++-- compact_str/src/repr/mod.rs | 10 +++---- compact_str/src/tests.rs | 27 +++++++++++++++++ 3 files changed, 88 insertions(+), 8 deletions(-) diff --git a/compact_str/src/lib.rs b/compact_str/src/lib.rs index 08244da4..c6819ed6 100644 --- a/compact_str/src/lib.rs +++ b/compact_str/src/lib.rs @@ -624,8 +624,7 @@ impl CompactString { /// /// # Safety /// * All Rust strings, including `CompactString`, must be valid UTF-8. The caller must - /// guarantee - /// that any modifications made to the underlying buffer are valid UTF-8. + /// guarantee that any modifications made to the underlying buffer are valid UTF-8. /// /// # Examples /// ``` @@ -2027,30 +2026,84 @@ impl BorrowMut for CompactString { impl Eq for CompactString {} -impl> PartialEq for CompactString { +impl + ?Sized> PartialEq for CompactString { fn eq(&self, other: &T) -> bool { self.as_str() == other.as_ref() } } +impl PartialEq for &CompactString { + fn eq(&self, other: &CompactString) -> bool { + self.as_str() == other.as_str() + } +} + impl PartialEq for String { fn eq(&self, other: &CompactString) -> bool { self.as_str() == other.as_str() } } +impl<'a> PartialEq<&'a CompactString> for String { + fn eq(&self, other: &&CompactString) -> bool { + self.as_str() == other.as_str() + } +} + +impl PartialEq for &String { + fn eq(&self, other: &CompactString) -> bool { + self.as_str() == other.as_str() + } +} + +impl PartialEq for str { + fn eq(&self, other: &CompactString) -> bool { + self == other.as_str() + } +} + +impl<'a> PartialEq<&'a CompactString> for str { + fn eq(&self, other: &&CompactString) -> bool { + self == other.as_str() + } +} + impl PartialEq for &str { fn eq(&self, other: &CompactString) -> bool { *self == other.as_str() } } +impl PartialEq for &&str { + fn eq(&self, other: &CompactString) -> bool { + **self == other.as_str() + } +} + impl<'a> PartialEq for Cow<'a, str> { fn eq(&self, other: &CompactString) -> bool { *self == other.as_str() } } +impl<'a> PartialEq for &Cow<'a, str> { + fn eq(&self, other: &CompactString) -> bool { + *self == other.as_str() + } +} + +impl PartialEq for &CompactString { + fn eq(&self, other: &String) -> bool { + self.as_str() == other.as_str() + } +} + +impl<'a> PartialEq> for &CompactString { + fn eq(&self, other: &Cow<'a, str>) -> bool { + self.as_str() == other + } +} + impl Ord for CompactString { fn cmp(&self, other: &Self) -> Ordering { self.as_str().cmp(other.as_str()) diff --git a/compact_str/src/repr/mod.rs b/compact_str/src/repr/mod.rs index 57f1a69c..653cb6e9 100644 --- a/compact_str/src/repr/mod.rs +++ b/compact_str/src/repr/mod.rs @@ -607,7 +607,7 @@ impl Repr { /// /// # SAFETY /// * The caller must guarantee that the provided [`Repr`] is actually a [`HeapBuffer`] by - /// checking the discriminant + /// checking the discriminant. /// /// Note: We used to define [`Repr`] as a `union` which implicitly transmuted between the two /// types, but that prevented us from defining a "niche" value to make `Option` @@ -621,7 +621,7 @@ impl Repr { /// /// # SAFETY /// * The caller must guarantee that the provided [`Repr`] is actually a [`HeapBuffer`] by - /// checking the discriminant + /// checking the discriminant. /// /// Note: We used to define [`Repr`] as a `union` which implicitly transmuted between the two /// types, but that prevented us from defining a "niche" value to make `Option` @@ -636,7 +636,7 @@ impl Repr { /// /// # SAFETY /// * The caller must guarantee that the provided [`Repr`] is actually a [`HeapBuffer`] by - /// checking the discriminant + /// checking the discriminant. /// /// Note: We used to define [`Repr`] as a `union` which implicitly transmuted between the two /// types, but that prevented us from defining a "niche" value to make `Option` @@ -651,7 +651,7 @@ impl Repr { /// /// # SAFETY /// * The caller must guarantee that the provided [`Repr`] is actually an [`InlineBuffer`] by - /// checking the discriminant + /// checking the discriminant. /// /// Note: We used to define [`Repr`] as a `union` which implicitly transmuted between the two /// types, but that prevented us from defining a "niche" value to make `Option` @@ -666,7 +666,7 @@ impl Repr { /// /// # SAFETY /// * The caller must guarantee that the provided [`Repr`] is actually an [`InlineBuffer`] by - /// checking the discriminant + /// checking the discriminant. /// /// Note: We used to define [`Repr`] as a `union` which implicitly transmuted between the two /// types, but that prevented us from defining a "niche" value to make `Option` diff --git a/compact_str/src/tests.rs b/compact_str/src/tests.rs index d8893ca3..a2c21874 100644 --- a/compact_str/src/tests.rs +++ b/compact_str/src/tests.rs @@ -639,6 +639,33 @@ fn test_plus_equals_operator_static_str() { assert_eq!(m, "ab"); } +// Allow these lints because we're explicitly testing impls for owned types and +// reference types. +#[allow(clippy::cmp_owned)] +#[allow(clippy::op_ref)] +#[test] +fn test_eq_operator() { + let x = CompactString::const_new("foo"); + let y = x.clone(); + + macro_rules! test_impl { + ($a:expr, $b:expr) => { + let _ = $a == $b; + let _ = &$a == $b; + let _ = &$a == &$b; + + let _ = $b == $a; + let _ = &$b == $a; + let _ = &$b == &$a; + }; + } + + test_impl!("a", x); + test_impl!(String::from("a"), x); + test_impl!(Cow::Borrowed("a"), x); + test_impl!(y, x); +} + #[test] fn test_u8_to_compact_string() { let vals = [u8::MIN, 1, 42, u8::MAX - 2, u8::MAX - 1, u8::MAX];