virtualization_rs/
base.rs1use std::marker::PhantomData;
4use std::slice;
5use std::str;
6
7use block::Block;
8use libc::c_void;
9use objc::rc::StrongPtr;
10use objc::runtime::{Object, BOOL, NO, YES};
11use objc::{class, msg_send, sel, sel_impl};
12
13#[link(name = "Virtualization", kind = "framework")]
14extern "C" {}
15
16#[link(name = "Foundation", kind = "framework")]
17extern "C" {
18 pub fn dispatch_queue_create(label: *const libc::c_char, attr: Id) -> Id;
19 pub fn dispatch_sync(queue: Id, block: *mut c_void);
21 pub fn dispatch_async(queue: Id, block: &Block<(), ()>);
22}
24
25pub type Id = *mut Object;
26pub const NIL: Id = 0 as Id;
27
28pub struct NSArray<T> {
29 pub _phantom: PhantomData<T>,
30 pub p: StrongPtr,
31}
32
33impl<T> NSArray<T> {
34 pub fn array_with_objects(objects: Vec<Id>) -> NSArray<T> {
35 unsafe {
36 let p = StrongPtr::new(
37 msg_send![class!(NSArray), arrayWithObjects:objects.as_slice().as_ptr() count:objects.len()],
38 );
39 NSArray {
40 p: p,
41 _phantom: PhantomData,
42 }
43 }
44 }
45
46 pub fn count(&self) -> usize {
47 unsafe { msg_send![*self.p, count] }
48 }
49}
50
51impl<T: From<StrongPtr>> NSArray<T> {
52 pub fn object_at_index(&self, index: usize) -> T {
53 debug_assert!(index < self.count());
54 unsafe { T::from(StrongPtr::retain(msg_send![*self.p, objectAtIndex: index])) }
55 }
56}
57
58const UTF8_ENCODING: usize = 4;
59pub struct NSString(pub StrongPtr);
60
61impl NSString {
62 pub fn new(string: &str) -> NSString {
63 unsafe {
64 let alloc: Id = msg_send![class!(NSString), alloc];
65 let p = StrongPtr::new(
66 msg_send![alloc, initWithBytes:string.as_ptr() length:string.len() encoding:UTF8_ENCODING as Id],
67 );
68 NSString(p)
69 }
70 }
71
72 pub fn len(&self) -> usize {
73 unsafe { msg_send![*self.0, lengthOfBytesUsingEncoding: UTF8_ENCODING] }
74 }
75
76 pub fn as_str(&self) -> &str {
77 unsafe {
78 let bytes = {
79 let bytes: *const libc::c_char = msg_send![*self.0, UTF8String];
80 bytes as *const u8
81 };
82 let len = self.len();
83 let bytes = slice::from_raw_parts(bytes, len);
84 str::from_utf8(bytes).unwrap()
85 }
86 }
87}
88
89impl From<StrongPtr> for NSString {
90 fn from(p: StrongPtr) -> Self {
91 NSString(p)
92 }
93}
94
95pub struct NSURL(pub StrongPtr);
96
97impl NSURL {
98 pub fn url_with_string(url: &str) -> NSURL {
99 unsafe {
100 let url_nsstring = NSString::new(url);
101 let p = StrongPtr::retain(msg_send![class!(NSURL), URLWithString: url_nsstring]);
102 NSURL(p)
103 }
104 }
105
106 pub fn file_url_with_path(path: &str, is_directory: bool) -> NSURL {
107 unsafe {
108 let path_nsstring = NSString::new(path);
109 let is_directory_ = if is_directory { YES } else { NO };
110 let p = StrongPtr::retain(
111 msg_send![class!(NSURL), fileURLWithPath:path_nsstring isDirectory:is_directory_],
112 );
113 NSURL(p)
114 }
115 }
116
117 pub fn check_resource_is_reachable_and_return_error(&self) -> bool {
118 let b = unsafe {
119 let obj: Id = msg_send![*self.0, checkResourceIsReachableAndReturnError: NIL];
120 obj as BOOL
121 };
122 b == YES
123 }
124
125 pub fn absolute_url(&self) -> NSURL {
126 unsafe {
127 let p = StrongPtr::retain(msg_send![*self.0, absoluteURL]);
128 NSURL(p)
129 }
130 }
131}
132
133pub struct NSFileHandle(pub StrongPtr);
134
135impl NSFileHandle {
136 pub fn new() -> NSFileHandle {
137 unsafe {
138 let p = StrongPtr::new(msg_send![class!(NSFileHandle), new]);
139 NSFileHandle(p)
140 }
141 }
142
143 pub fn file_handle_with_standard_input() -> NSFileHandle {
144 unsafe {
145 let p = StrongPtr::retain(msg_send![class!(NSFileHandle), fileHandleWithStandardInput]);
146 NSFileHandle(p)
147 }
148 }
149
150 pub fn file_handle_with_standard_output() -> NSFileHandle {
151 unsafe {
152 let p = StrongPtr::retain(msg_send![
153 class!(NSFileHandle),
154 fileHandleWithStandardOutput
155 ]);
156 NSFileHandle(p)
157 }
158 }
159}
160
161pub struct NSDictionary(pub StrongPtr);
162
163impl NSDictionary {
164 pub fn all_keys<T>(&self) -> NSArray<T> {
165 unsafe {
166 NSArray {
167 p: StrongPtr::retain(msg_send![*self.0, allKeys]),
168 _phantom: PhantomData,
169 }
170 }
171 }
172
173 pub fn all_values<T>(&self) -> NSArray<T> {
174 unsafe {
175 NSArray {
176 p: StrongPtr::retain(msg_send![*self.0, allValues]),
177 _phantom: PhantomData,
178 }
179 }
180 }
181}
182
183pub struct NSError(pub StrongPtr);
184
185impl NSError {
186 pub fn nil() -> NSError {
187 unsafe {
188 let p = StrongPtr::new(NIL);
189 NSError(p)
190 }
191 }
192
193 pub fn code(&self) -> isize {
194 unsafe { msg_send![*self.0, code] }
195 }
196
197 pub fn localized_description(&self) -> NSString {
198 unsafe { NSString(StrongPtr::retain(msg_send![*self.0, localizedDescription])) }
199 }
200
201 pub fn localized_failure_reason(&self) -> NSString {
202 unsafe {
203 NSString(StrongPtr::retain(msg_send![
204 *self.0,
205 localizedFailureReason
206 ]))
207 }
208 }
209
210 pub fn localized_recovery_suggestion(&self) -> NSString {
211 unsafe {
212 NSString(StrongPtr::retain(msg_send![
213 *self.0,
214 localizedRecoverySuggestion
215 ]))
216 }
217 }
218
219 pub fn help_anchor(&self) -> NSString {
220 unsafe { NSString(StrongPtr::retain(msg_send![*self.0, helpAnchor])) }
221 }
222
223 pub fn user_info(&self) -> NSDictionary {
224 unsafe { NSDictionary(StrongPtr::retain(msg_send![*self.0, userInfo])) }
225 }
226
227 pub fn dump(&self) {
228 let code = self.code();
229 println!("code: {}", code);
230 let localized_description = self.localized_description();
231 println!("localizedDescription : {}", localized_description.as_str());
232 let localized_failure_reason = self.localized_failure_reason();
233 println!(
234 "localizedFailureReason : {}",
235 localized_failure_reason.as_str()
236 );
237 let localized_recovery_suggestion = self.localized_recovery_suggestion();
238 println!(
239 "localizedRecoverySuggestion : {}",
240 localized_recovery_suggestion.as_str()
241 );
242 let help_anchor = self.help_anchor();
243 println!("helpAnchor : {}", help_anchor.as_str());
244 let user_info = self.user_info();
245 println!("userInfo :");
246 let keys: NSArray<NSString> = user_info.all_keys();
247 let values: NSArray<NSString> = user_info.all_values();
248 let cnt = keys.count();
249 for i in 0..cnt {
250 let k = keys.object_at_index(i);
251 let o = values.object_at_index(i);
252 println!(" key: {}, value: {}", k.as_str(), o.as_str());
253 }
254 }
255}