-
Notifications
You must be signed in to change notification settings - Fork 569
Expand file tree
/
Copy pathutil.rs
More file actions
64 lines (56 loc) · 2.17 KB
/
util.rs
File metadata and controls
64 lines (56 loc) · 2.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
// Copyright 2019 The xi-editor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//! Utilities, macOS specific.
use std::ffi::c_void;
use cocoa::base::{id, nil, BOOL, YES};
use cocoa::foundation::{NSAutoreleasePool, NSString, NSUInteger};
use objc::{class, msg_send, sel, sel_impl};
/// Panic if not on the main thread.assert_main_thread()
///
/// Many Cocoa operations are only valid on the main thread, and (I think)
/// undefined behavior is possible if invoked from other threads. If so,
/// failing on non main thread is necessary for safety.
pub(crate) fn assert_main_thread() {
unsafe {
let is_main_thread: BOOL = msg_send!(class!(NSThread), isMainThread);
assert_eq!(is_main_thread, YES);
}
}
/// Create a new NSString from a &str.
pub(crate) fn make_nsstring(s: &str) -> id {
unsafe { NSString::alloc(nil).init_str(s).autorelease() }
}
pub(crate) fn from_nsstring(s: id) -> String {
unsafe {
let slice = std::slice::from_raw_parts(s.UTF8String() as *const _, s.len());
let result = std::str::from_utf8_unchecked(slice);
result.into()
}
}
pub(crate) fn make_nsdata(bytes: &[u8]) -> id {
let dlen = bytes.len() as NSUInteger;
unsafe {
msg_send![class!(NSData), dataWithBytes: bytes.as_ptr() as *const c_void length: dlen]
}
}
pub(crate) fn from_nsdata(data: id) -> Vec<u8> {
unsafe {
let len: NSUInteger = msg_send![data, length];
let bytes: *const c_void = msg_send![data, bytes];
let mut out: Vec<u8> = Vec::with_capacity(len as usize);
std::ptr::copy_nonoverlapping(bytes as *const u8, out.as_mut_ptr(), len as usize);
out.set_len(len as usize);
out
}
}