Skip to content

Commit a10fec8

Browse files
authored
Merge pull request #124 from madsmtm/bigger-foundation
Add more classes to `objc2-foundation`
2 parents 3fc99b5 + 2c586a6 commit a10fec8

14 files changed

+1288
-36
lines changed

objc2-foundation/CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,18 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
1111
`NSArray`, which derefs to `NSObject`, which derefs to `Object`.
1212

1313
This allows more ergonomic usage.
14+
* Implement `PartialOrd` and `Ord` for `NSString` and `NSRange`.
15+
* Added `NSString::has_prefix` and `NSString::has_suffix`.
16+
* Added `NSRange` methods `new`, `is_empty`, `contains` and `end`.
17+
* Added `NSThread` object.
18+
* Added `is_multi_threaded` and `is_main_thread` helper functions.
19+
* Added `NSProcessInfo` object.
20+
* Added `NSMutableData` methods `from_data`, `with_capacity` and `push`.
21+
* Added `io::Write` and `iter::Extend` implementation for `NSMutableData`.
22+
* Added `NSUUID` object.
23+
* Added `NSMutableString` object.
24+
* Added basic `NSAttributedString` object.
25+
* Added basic `NSMutableAttributedString` object.
1426

1527
### Changed
1628
* **BREAKING**: Removed the following helper traits in favor of inherent
@@ -32,6 +44,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
3244
- `INSCopying` (now `NSCopying`)
3345
- `INSMutableCopying` (now `NSMutableCopying`)
3446
- `INSFastEnumeration` (now `NSFastEnumeration`)
47+
* **BREAKING**: Renamed `NSMutableData::append` to `extend_from_slice`.
3548

3649

3750
## 0.2.0-alpha.4 - 2022-01-03
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
use core::ptr::NonNull;
2+
3+
use objc2::msg_send;
4+
use objc2::rc::{DefaultId, Id, Shared};
5+
use objc2::runtime::Object;
6+
7+
use crate::{
8+
NSCopying, NSDictionary, NSMutableAttributedString, NSMutableCopying, NSObject, NSString,
9+
};
10+
11+
object! {
12+
/// A string that has associated attributes for portions of its text.
13+
///
14+
/// Examples of attributes could be: Visual style, hyperlinks, or
15+
/// accessibility data.
16+
///
17+
/// Conceptually, each UTF-16 code unit in an attributed string has its
18+
/// own collection of attributes - most often though
19+
///
20+
/// Only the most basic functionality is defined here, the `AppKit`
21+
/// framework contains most of the extension methods.
22+
///
23+
/// See [Apple's documentation](https://developer.apple.com/documentation/foundation/nsattributedstring?language=objc).
24+
unsafe pub struct NSAttributedString: NSObject;
25+
}
26+
27+
// TODO: SAFETY
28+
unsafe impl Sync for NSAttributedString {}
29+
unsafe impl Send for NSAttributedString {}
30+
31+
/// Attributes that you can apply to text in an attributed string.
32+
pub type NSAttributedStringKey = NSString;
33+
34+
/// Creating attributed strings.
35+
impl NSAttributedString {
36+
unsafe_def_fn! {
37+
/// Construct an empty attributed string.
38+
pub fn new -> Shared;
39+
}
40+
41+
/// Creates a new attributed string from the given string and attributes.
42+
///
43+
/// The attributes are associated with every UTF-16 code unit in the
44+
/// string.
45+
#[doc(alias = "initWithString:")]
46+
pub fn new_with_attributes(
47+
string: &NSString,
48+
// TODO: Mutability of the dictionary should be (Shared, Shared)
49+
attributes: &NSDictionary<NSAttributedStringKey, Object>,
50+
) -> Id<Self, Shared> {
51+
unsafe {
52+
let obj: *mut Self = msg_send![Self::class(), alloc];
53+
let obj: *mut Self = msg_send![obj, initWithString: string, attributes: attributes];
54+
Id::new(NonNull::new_unchecked(obj))
55+
}
56+
}
57+
58+
/// Creates a new attributed string without any attributes.
59+
#[doc(alias = "initWithString:")]
60+
pub fn from_nsstring(string: &NSString) -> Id<Self, Shared> {
61+
unsafe {
62+
let obj: *mut Self = msg_send![Self::class(), alloc];
63+
let obj: *mut Self = msg_send![obj, initWithString: string];
64+
Id::new(NonNull::new_unchecked(obj))
65+
}
66+
}
67+
}
68+
69+
/// Querying.
70+
impl NSAttributedString {
71+
// TODO: Lifetimes?
72+
pub fn string(&self) -> &NSString {
73+
unsafe { msg_send![self, string] }
74+
}
75+
76+
/// Alias for `self.string().len_utf16()`.
77+
#[doc(alias = "length")]
78+
#[allow(unused)]
79+
// TODO: Finish this
80+
fn len_utf16(&self) -> usize {
81+
unsafe { msg_send![self, length] }
82+
}
83+
84+
// /// TODO
85+
// ///
86+
// /// See [Apple's documentation on Effective and Maximal Ranges][doc].
87+
// ///
88+
// /// [doc]: https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/AttributedStrings/Tasks/AccessingAttrs.html#//apple_ref/doc/uid/20000161-SW2
89+
// #[doc(alias = "attributesAtIndex:effectiveRange:")]
90+
// pub fn attributes_in_effective_range(
91+
// &self,
92+
// index: usize,
93+
// range: Range<usize>,
94+
// ) -> Id<Self, Shared> {
95+
// let range = NSRange::from(range);
96+
// todo!()
97+
// }
98+
//
99+
// attributesAtIndex:longestEffectiveRange:inRange:
100+
101+
// TODO: attributedSubstringFromRange:
102+
// TODO: enumerateAttributesInRange:options:usingBlock:
103+
}
104+
105+
impl DefaultId for NSAttributedString {
106+
type Ownership = Shared;
107+
108+
#[inline]
109+
fn default_id() -> Id<Self, Self::Ownership> {
110+
Self::new()
111+
}
112+
}
113+
114+
unsafe impl NSCopying for NSAttributedString {
115+
type Ownership = Shared;
116+
type Output = NSAttributedString;
117+
}
118+
119+
unsafe impl NSMutableCopying for NSAttributedString {
120+
type Output = NSMutableAttributedString;
121+
}
122+
123+
#[cfg(test)]
124+
mod tests {
125+
use alloc::string::ToString;
126+
use objc2::rc::autoreleasepool;
127+
128+
use super::*;
129+
130+
#[test]
131+
fn test_new() {
132+
let s = NSAttributedString::new();
133+
assert_eq!(&s.string().to_string(), "");
134+
}
135+
136+
#[test]
137+
fn test_string_bound_to_attributed() {
138+
let attr_s = {
139+
let source = NSString::from_str("Hello world!");
140+
NSAttributedString::from_nsstring(&source)
141+
};
142+
let s = autoreleasepool(|_| attr_s.string());
143+
assert_eq!(s.len(), 12);
144+
}
145+
146+
#[test]
147+
fn test_from_nsstring() {
148+
let s = NSAttributedString::from_nsstring(&NSString::from_str("abc"));
149+
assert_eq!(&s.string().to_string(), "abc");
150+
}
151+
152+
#[test]
153+
fn test_copy() {
154+
let s1 = NSAttributedString::from_nsstring(&NSString::from_str("abc"));
155+
let s2 = s1.copy();
156+
// NSAttributedString performs this optimization in GNUStep's runtime,
157+
// but not in Apple's; so we don't test for it!
158+
// assert_eq!(s1.as_ptr(), s2.as_ptr());
159+
assert!(s2.is_kind_of(NSAttributedString::class()));
160+
161+
let s3 = s1.mutable_copy();
162+
assert_ne!(s1.as_ptr(), s3.as_ptr() as *mut NSAttributedString);
163+
assert!(s3.is_kind_of(NSMutableAttributedString::class()));
164+
}
165+
}

objc2-foundation/src/comparison_result.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,22 @@ use core::cmp::Ordering;
22

33
use objc2::{Encode, Encoding, RefEncode};
44

5+
/// Constants that indicate sort order.
6+
///
7+
/// See [Apple's documentation](https://developer.apple.com/documentation/foundation/nscomparisonresult?language=objc).
58
#[repr(isize)] // NSInteger
69
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
710
pub enum NSComparisonResult {
11+
/// The left operand is smaller than the right operand.
812
Ascending = -1,
13+
/// The two operands are equal.
914
Same = 0,
15+
/// The left operand is greater than the right operand.
1016
Descending = 1,
1117
}
1218

1319
impl Default for NSComparisonResult {
20+
#[inline]
1421
fn default() -> Self {
1522
Self::Same
1623
}
@@ -25,6 +32,7 @@ unsafe impl RefEncode for NSComparisonResult {
2532
}
2633

2734
impl From<Ordering> for NSComparisonResult {
35+
#[inline]
2836
fn from(order: Ordering) -> Self {
2937
match order {
3038
Ordering::Less => Self::Ascending,
@@ -35,6 +43,7 @@ impl From<Ordering> for NSComparisonResult {
3543
}
3644

3745
impl From<NSComparisonResult> for Ordering {
46+
#[inline]
3847
fn from(comparison_result: NSComparisonResult) -> Self {
3948
match comparison_result {
4049
NSComparisonResult::Ascending => Self::Less,

0 commit comments

Comments
 (0)