From db6924cc6c8283c2e774be94e00e17db28368f29 Mon Sep 17 00:00:00 2001 From: Muhammad Hamza Date: Sat, 27 Aug 2022 23:17:03 +0500 Subject: [PATCH 1/4] Add impl From> for IString --- src/string.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/string.rs b/src/string.rs index 4474a8c..e0cbe0e 100644 --- a/src/string.rs +++ b/src/string.rs @@ -1,3 +1,4 @@ +use std::borrow::Cow; use std::fmt::Debug; /// An immutable string type inspired by [Immutable.js](https://immutable-js.com/). @@ -65,6 +66,15 @@ impl From> for IString { } } +impl From> for IString { + fn from(cow: Cow<'static, str>) -> Self { + match cow { + Cow::Borrowed(s) => IString::Static(s), + Cow::Owned(s) => s.into(), + } + } +} + impl PartialEq for IString { fn eq(&self, other: &IString) -> bool { self.as_str().eq(other.as_str()) From 39c406420aa2e0e0bec49cc01dc06348b3adb859 Mon Sep 17 00:00:00 2001 From: Muhammad Hamza Date: Sat, 27 Aug 2022 23:24:32 +0500 Subject: [PATCH 2/4] IString.as_cow helper This is helpful in cases like passing the IString to a function which takes a Cow without needing to clone the content --- src/string.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/string.rs b/src/string.rs index e0cbe0e..df0548c 100644 --- a/src/string.rs +++ b/src/string.rs @@ -32,6 +32,21 @@ impl IString { Self::Rc(s) => &*s, } } + + /// Obtain the contents of [`IString`] as a [`Cow`]. + /// + /// # Examples + /// + /// ``` + /// # use implicit_clone::unsync::IString; + /// use std::borrow::Cow; + /// let s = IString::from("foo"); + /// + /// let cow: Cow<'_, str> = s.as_cow(); + /// ``` + pub fn as_cow(&self) -> Cow<'_, str> { + Cow::Borrowed(self.as_str()) + } } impl Default for IString { From 2f3e899880b745209d6d20d5b3c122f279181bf0 Mon Sep 17 00:00:00 2001 From: Muhammad Hamza Date: Sat, 27 Aug 2022 23:28:30 +0500 Subject: [PATCH 3/4] Add test --- src/string.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/string.rs b/src/string.rs index df0548c..3a8de1b 100644 --- a/src/string.rs +++ b/src/string.rs @@ -189,4 +189,16 @@ mod test_string { assert_eq!(map.get("foo").copied(), Some(true)); assert_eq!(map.get("bar").copied(), Some(true)); } + + #[test] + fn as_cow_does_not_clone() { + let rc_s = Rc::from("foo"); + let s = IString::Rc(Rc::clone(&rc_s)); + assert_eq!(Rc::strong_count(&rc_s), 2); + let cow: Cow<'_, str> = s.as_cow(); + assert_eq!(Rc::strong_count(&rc_s), 2); + // this assert exists to ensure the cow lives after the strong_count asset + assert_eq!(cow, "foo"); + + } } From b10144eedb27eb6e000f6aad62e0e9b4f5c5e376 Mon Sep 17 00:00:00 2001 From: Muhammad Hamza Date: Sat, 27 Aug 2022 23:39:37 +0500 Subject: [PATCH 4/4] Fix some clippy --- src/string.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/string.rs b/src/string.rs index 3a8de1b..d5ee207 100644 --- a/src/string.rs +++ b/src/string.rs @@ -28,8 +28,8 @@ impl IString { /// ``` pub fn as_str(&self) -> &str { match self { - Self::Static(s) => *s, - Self::Rc(s) => &*s, + Self::Static(s) => s, + Self::Rc(s) => s, } }