From b9957d4403bfbdbe13287db90972f434c48b711f Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Fri, 6 Sep 2024 14:52:22 +0200 Subject: [PATCH] Implement more traits on Retained Implement `fmt` traits, as well as `Extend` on `Retained`, to make these easier to use when implemented on downstream types. --- crates/objc2/CHANGELOG.md | 2 + .../objc2/src/rc/retained_forwarding_impls.rs | 65 ++++++++++++++++--- .../src/tests/mutable_data.rs | 6 +- .../objc2-foundation/src/tests/mutable_set.rs | 4 +- .../src/tests/mutable_string.rs | 6 +- 5 files changed, 66 insertions(+), 17 deletions(-) diff --git a/crates/objc2/CHANGELOG.md b/crates/objc2/CHANGELOG.md index d6baedf1d..2c50e1a47 100644 --- a/crates/objc2/CHANGELOG.md +++ b/crates/objc2/CHANGELOG.md @@ -17,6 +17,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). * Added `IsMainThreadOnly::mtm`. * Added `DowncastTarget`, `AnyObject::downcast_ref` and `Retained::downcast` to allow safely casting between Objective-C objects. +* Implemented more `fmt` traits on `Retained`. +* Implemented `Extend` trait on `Retained`. ### Changed * **BREAKING**: Changed how you specify a class to only be available on the diff --git a/crates/objc2/src/rc/retained_forwarding_impls.rs b/crates/objc2/src/rc/retained_forwarding_impls.rs index 7236b7b9e..389b41e8c 100644 --- a/crates/objc2/src/rc/retained_forwarding_impls.rs +++ b/crates/objc2/src/rc/retained_forwarding_impls.rs @@ -1,8 +1,6 @@ //! Trivial forwarding impls on `Retained`. //! //! Kept here to keep `id.rs` free from this boilerplate. -//! -//! `#[inline]` is used where the standard library `Box` uses it. #![forbid(unsafe_code)] @@ -168,15 +166,44 @@ where } } -impl fmt::Display for Retained { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - (**self).fmt(f) - } +macro_rules! forward_fmt_impl { + ($trait:path) => { + impl $trait for Retained { + #[inline] + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + (**self).fmt(f) + } + } + }; } -impl fmt::Debug for Retained { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - (**self).fmt(f) +forward_fmt_impl!(fmt::Binary); +forward_fmt_impl!(fmt::Debug); +forward_fmt_impl!(fmt::Display); +forward_fmt_impl!(fmt::LowerExp); +forward_fmt_impl!(fmt::LowerHex); +forward_fmt_impl!(fmt::Octal); +// forward_fmt_impl!(fmt::Pointer); +forward_fmt_impl!(fmt::UpperExp); +forward_fmt_impl!(fmt::UpperHex); + +impl<'a, T: ?Sized> fmt::Write for &'a Retained +where + &'a T: fmt::Write, +{ + #[inline] + fn write_str(&mut self, s: &str) -> fmt::Result { + (&***self).write_str(s) + } + + #[inline] + fn write_char(&mut self, c: char) -> fmt::Result { + (&***self).write_char(c) + } + + #[inline] + fn write_fmt(&mut self, args: fmt::Arguments<'_>) -> fmt::Result { + (&***self).write_fmt(args) } } @@ -361,4 +388,24 @@ where } } +impl Extend for Retained +where + for<'a> &'a T: Extend, +{ + #[inline] + fn extend>(&mut self, iter: I) { + (&**self).extend(iter) + } +} + +impl<'a, A, T: ?Sized> Extend for &'a Retained +where + &'a T: Extend, +{ + #[inline] + fn extend>(&mut self, iter: I) { + (&***self).extend(iter) + } +} + // TODO: impl Fn traits, CoerceUnsized, Stream and so on when stabilized diff --git a/framework-crates/objc2-foundation/src/tests/mutable_data.rs b/framework-crates/objc2-foundation/src/tests/mutable_data.rs index b061cb263..34c26f093 100644 --- a/framework-crates/objc2-foundation/src/tests/mutable_data.rs +++ b/framework-crates/objc2-foundation/src/tests/mutable_data.rs @@ -65,9 +65,9 @@ fn test_with_capacity() { #[test] fn test_extend() { - let data = NSMutableData::with_bytes(&[1, 2]); - (&*data).extend(3..=5); + let mut data = NSMutableData::with_bytes(&[1, 2]); + data.extend(3..=5); assert_eq!(data.to_vec(), &[1, 2, 3, 4, 5]); - (&*data).extend(&*NSData::with_bytes(&[6, 7])); + (&data).extend(&*NSData::with_bytes(&[6, 7])); assert_eq!(data.to_vec(), &[1, 2, 3, 4, 5, 6, 7]); } diff --git a/framework-crates/objc2-foundation/src/tests/mutable_set.rs b/framework-crates/objc2-foundation/src/tests/mutable_set.rs index e0641ca70..5c0060488 100644 --- a/framework-crates/objc2-foundation/src/tests/mutable_set.rs +++ b/framework-crates/objc2-foundation/src/tests/mutable_set.rs @@ -68,10 +68,10 @@ fn test_to_vec() { #[test] fn test_extend() { - let set = NSMutableSet::new(); + let mut set = NSMutableSet::new(); assert!(set.is_empty()); - (&*set).extend([ns_string!("one"), ns_string!("two"), ns_string!("three")]); + set.extend([ns_string!("one"), ns_string!("two"), ns_string!("three")]); assert_eq!(set.len(), 3); } diff --git a/framework-crates/objc2-foundation/src/tests/mutable_string.rs b/framework-crates/objc2-foundation/src/tests/mutable_string.rs index 197370dd7..71cfd7b00 100644 --- a/framework-crates/objc2-foundation/src/tests/mutable_string.rs +++ b/framework-crates/objc2-foundation/src/tests/mutable_string.rs @@ -111,11 +111,11 @@ fn write_same_string() { let mut expected = String::from("foo"); for i in 0..3 { - write!(&mut &*string, "{string}").unwrap(); - write!(&mut &*string, "{string:?}").unwrap(); + write!(&string, "{string}").unwrap(); + write!(&string, "{string:?}").unwrap(); // Test `NSObject`'s Debug impl as well. let object: &NSObject = &string; - write!(&mut &*string, "{object:?}").unwrap(); + write!(&string, "{object:?}").unwrap(); let expected_clone = expected.clone(); write!(&mut expected, "{expected_clone}").unwrap();