Skip to content

Commit

Permalink
Implement more traits on Retained
Browse files Browse the repository at this point in the history
Implement `fmt` traits, as well as `Extend` on `Retained`, to make these
easier to use when implemented on downstream types.
  • Loading branch information
madsmtm committed Sep 18, 2024
1 parent 55a1cff commit b9957d4
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 17 deletions.
2 changes: 2 additions & 0 deletions crates/objc2/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
65 changes: 56 additions & 9 deletions crates/objc2/src/rc/retained_forwarding_impls.rs
Original file line number Diff line number Diff line change
@@ -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)]

Expand Down Expand Up @@ -168,15 +166,44 @@ where
}
}

impl<T: fmt::Display + ?Sized> fmt::Display for Retained<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
(**self).fmt(f)
}
macro_rules! forward_fmt_impl {
($trait:path) => {
impl<T: $trait + ?Sized> $trait for Retained<T> {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
(**self).fmt(f)
}
}
};
}

impl<T: fmt::Debug + ?Sized> fmt::Debug for Retained<T> {
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<T>
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)
}
}

Expand Down Expand Up @@ -361,4 +388,24 @@ where
}
}

impl<A, T: ?Sized> Extend<A> for Retained<T>
where
for<'a> &'a T: Extend<A>,
{
#[inline]
fn extend<I: IntoIterator<Item = A>>(&mut self, iter: I) {
(&**self).extend(iter)
}
}

impl<'a, A, T: ?Sized> Extend<A> for &'a Retained<T>
where
&'a T: Extend<A>,
{
#[inline]
fn extend<I: IntoIterator<Item = A>>(&mut self, iter: I) {
(&***self).extend(iter)
}
}

// TODO: impl Fn traits, CoerceUnsized, Stream and so on when stabilized
6 changes: 3 additions & 3 deletions framework-crates/objc2-foundation/src/tests/mutable_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]);
}
4 changes: 2 additions & 2 deletions framework-crates/objc2-foundation/src/tests/mutable_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down
6 changes: 3 additions & 3 deletions framework-crates/objc2-foundation/src/tests/mutable_string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down

0 comments on commit b9957d4

Please sign in to comment.