From 0b42ca9fa7759f17ae5a26718ca06d59aae5d1fc Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Sun, 31 Oct 2021 18:04:50 +0100 Subject: [PATCH] Improve NSMutableData --- objc2_foundation/src/data.rs | 82 +++++++++++++++++++++--------------- 1 file changed, 48 insertions(+), 34 deletions(-) diff --git a/objc2_foundation/src/data.rs b/objc2_foundation/src/data.rs index 263c61665..04c0821d6 100644 --- a/objc2_foundation/src/data.rs +++ b/objc2_foundation/src/data.rs @@ -1,6 +1,6 @@ #[cfg(feature = "block")] use alloc::vec::Vec; -use core::ops::Range; +use core::ops::{Deref, DerefMut, Range}; use core::slice; use core::{ffi::c_void, ptr::NonNull}; @@ -98,45 +98,45 @@ unsafe impl INSMutableCopying for NSData { type Output = NSMutableData; } +impl Deref for NSData { + type Target = [u8]; + + fn deref(&self) -> &[u8] { + self.bytes() + } +} + pub unsafe trait INSMutableData: INSData { fn bytes_mut(&mut self) -> &mut [u8] { let ptr: *mut c_void = unsafe { msg_send![self, mutableBytes] }; // The bytes pointer may be null for length zero - let (ptr, len) = if ptr.is_null() { - (0x1 as *mut u8, 0) + if ptr.is_null() { + &mut [] } else { - (ptr as *mut u8, self.len()) - }; - unsafe { slice::from_raw_parts_mut(ptr, len) } + unsafe { slice::from_raw_parts_mut(ptr as *mut u8, self.len()) } + } } + /// Expands with zeroes, or truncates the buffer. fn set_len(&mut self, len: usize) { - unsafe { - let _: () = msg_send![self, setLength: len]; - } + unsafe { msg_send![self, setLength: len] } } fn append(&mut self, bytes: &[u8]) { let bytes_ptr = bytes.as_ptr() as *const c_void; - unsafe { - let _: () = msg_send![ - self, - appendBytes: bytes_ptr, - length:bytes.len(), - ]; - } + unsafe { msg_send![self, appendBytes: bytes_ptr, length: bytes.len()] } } fn replace_range(&mut self, range: Range, bytes: &[u8]) { let range = NSRange::from(range); let bytes_ptr = bytes.as_ptr() as *const c_void; unsafe { - let _: () = msg_send![ + msg_send![ self, - replaceBytesInRange:range, - withBytes:bytes_ptr, - length:bytes.len(), - ]; + replaceBytesInRange: range, + withBytes: bytes_ptr, + length: bytes.len(), + ] } } @@ -160,6 +160,20 @@ unsafe impl INSMutableCopying for NSMutableData { type Output = NSMutableData; } +impl Deref for NSMutableData { + type Target = [u8]; + + fn deref(&self) -> &[u8] { + self.bytes() + } +} + +impl DerefMut for NSMutableData { + fn deref_mut(&mut self) -> &mut [u8] { + self.bytes_mut() + } +} + #[cfg(test)] mod tests { use super::{INSData, INSMutableData, NSData, NSMutableData}; @@ -171,8 +185,8 @@ mod tests { fn test_bytes() { let bytes = [3, 7, 16, 52, 112, 19]; let data = NSData::with_bytes(&bytes); - assert!(data.len() == bytes.len()); - assert!(data.bytes() == bytes); + assert_eq!(data.len(), bytes.len()); + assert_eq!(data.bytes(), bytes); } #[test] @@ -185,43 +199,43 @@ mod tests { fn test_bytes_mut() { let mut data = NSMutableData::with_bytes(&[7, 16]); data.bytes_mut()[0] = 3; - assert!(data.bytes() == [3, 16]); + assert_eq!(data.bytes(), [3, 16]); } #[test] fn test_set_len() { let mut data = NSMutableData::with_bytes(&[7, 16]); data.set_len(4); - assert!(data.len() == 4); - assert!(data.bytes() == [7, 16, 0, 0]); + assert_eq!(data.len(), 4); + assert_eq!(data.bytes(), [7, 16, 0, 0]); data.set_len(1); - assert!(data.len() == 1); - assert!(data.bytes() == [7]); + assert_eq!(data.len(), 1); + assert_eq!(data.bytes(), [7]); } #[test] fn test_append() { let mut data = NSMutableData::with_bytes(&[7, 16]); data.append(&[3, 52]); - assert!(data.len() == 4); - assert!(data.bytes() == [7, 16, 3, 52]); + assert_eq!(data.len(), 4); + assert_eq!(data.bytes(), [7, 16, 3, 52]); } #[test] fn test_replace() { let mut data = NSMutableData::with_bytes(&[7, 16]); data.replace_range(0..0, &[3]); - assert!(data.bytes() == [3, 7, 16]); + assert_eq!(data.bytes(), [3, 7, 16]); data.replace_range(1..2, &[52, 13]); - assert!(data.bytes() == [3, 52, 13, 16]); + assert_eq!(data.bytes(), [3, 52, 13, 16]); data.replace_range(2..4, &[6]); - assert!(data.bytes() == [3, 52, 6]); + assert_eq!(data.bytes(), [3, 52, 6]); data.set_bytes(&[8, 17]); - assert!(data.bytes() == [8, 17]); + assert_eq!(data.bytes(), [8, 17]); } #[cfg(feature = "block")]