Merge remote-tracking branch 'upstream/master'
Conflicts: src/appkit.rs
This commit is contained in:
+10
@@ -0,0 +1,10 @@
|
||||
os: osx
|
||||
|
||||
language: rust
|
||||
|
||||
branches:
|
||||
except:
|
||||
- master
|
||||
|
||||
notifications:
|
||||
webhooks: http://build.servo.org:54856/travis
|
||||
+10
-4
@@ -1,13 +1,19 @@
|
||||
[package]
|
||||
name = "cocoa"
|
||||
version = "0.1.1"
|
||||
description = "Bindings to Cocoa for OS X"
|
||||
homepage = "https://github.com/servo/cocoa-rs"
|
||||
repository = "https://github.com/servo/cocoa-rs"
|
||||
version = "0.4.4"
|
||||
authors = ["The Servo Project Developers"]
|
||||
license = "MIT"
|
||||
license = "MIT / Apache-2.0"
|
||||
|
||||
[lib]
|
||||
name = "cocoa"
|
||||
crate-type = ["rlib"]
|
||||
|
||||
[dependencies]
|
||||
bitflags = "0.1"
|
||||
libc = "*"
|
||||
block = "0.1"
|
||||
bitflags = "0.7"
|
||||
libc = "0.2"
|
||||
core-graphics = ">=0.2, <0.4"
|
||||
objc = "0.2"
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
Cocoa-rs
|
||||
--------
|
||||
|
||||
This crate provides Rust bindings to Cocoa for OSX. It's dual-licensed MIT /
|
||||
Apache 2.0. If you'd like to help improve cocoa-rs, check out [the Servo
|
||||
contributing guide](https://github.com/servo/servo/blob/master/CONTRIBUTING.md)!
|
||||
@@ -1,4 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
SRCDIR="$(cd $(dirname $0) && pwd)"
|
||||
sed "s#%VPATH%#${SRCDIR}#" ${SRCDIR}/Makefile.in > Makefile
|
||||
+11
-10
@@ -1,12 +1,13 @@
|
||||
extern crate cocoa;
|
||||
|
||||
use cocoa::base::{NSUInteger, selector, nil, YES, NO};
|
||||
use cocoa::appkit::{NSApp, NSRect, NSPoint, NSSize,
|
||||
NSAutoreleasePool, NSProcessInfo,
|
||||
use cocoa::base::{selector, nil, NO};
|
||||
use cocoa::foundation::{NSUInteger, NSRect, NSPoint, NSSize,
|
||||
NSAutoreleasePool, NSProcessInfo, NSString};
|
||||
use cocoa::appkit::{NSApp,
|
||||
NSApplication, NSApplicationActivationPolicyRegular,
|
||||
NSWindow, NSTitledWindowMask, NSBackingStoreBuffered,
|
||||
NSString,
|
||||
NSMenu, NSMenuItem};
|
||||
NSMenu, NSMenuItem, NSRunningApplication,
|
||||
NSApplicationActivateIgnoringOtherApps};
|
||||
|
||||
fn main() {
|
||||
unsafe {
|
||||
@@ -23,12 +24,12 @@ fn main() {
|
||||
|
||||
// create Application menu
|
||||
let app_menu = NSMenu::new(nil).autorelease();
|
||||
let quit_prefix = NSString::alloc(nil).init_str("Quit \0");
|
||||
let quit_prefix = NSString::alloc(nil).init_str("Quit");
|
||||
let quit_title = quit_prefix.stringByAppendingString_(
|
||||
NSProcessInfo::processInfo(nil).processName()
|
||||
);
|
||||
let quit_action = selector("terminate:");
|
||||
let quit_key = NSString::alloc(nil).init_str("q\0");
|
||||
let quit_key = NSString::alloc(nil).init_str("q");
|
||||
let quit_item = NSMenuItem::alloc(nil).initWithTitle_action_keyEquivalent_(
|
||||
quit_title,
|
||||
quit_action,
|
||||
@@ -46,11 +47,11 @@ fn main() {
|
||||
).autorelease();
|
||||
window.cascadeTopLeftFromPoint_(NSPoint::new(20., 20.));
|
||||
window.center();
|
||||
let title = NSString::alloc(nil).init_str("Hello World!\0");
|
||||
let title = NSString::alloc(nil).init_str("Hello World!");
|
||||
window.setTitle_(title);
|
||||
window.makeKeyAndOrderFront_(nil);
|
||||
|
||||
app.activateIgnoringOtherApps_(YES);
|
||||
let current_app = NSRunningApplication::currentApplication(nil);
|
||||
current_app.activateWithOptions_(NSApplicationActivateIgnoringOtherApps);
|
||||
app.run();
|
||||
}
|
||||
}
|
||||
|
||||
+1536
-487
File diff suppressed because it is too large
Load Diff
+10
-269
@@ -7,302 +7,43 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use libc;
|
||||
use std::ffi;
|
||||
use objc::runtime;
|
||||
use std::mem;
|
||||
|
||||
pub type Category = libc::intptr_t;
|
||||
pub type Class = libc::intptr_t;
|
||||
#[allow(non_camel_case_types)]
|
||||
pub type id = libc::intptr_t;
|
||||
pub type IMP = extern "C" fn(id, SEL) -> id;
|
||||
pub type Ivar = libc::intptr_t;
|
||||
pub type Method = libc::intptr_t;
|
||||
#[allow(non_camel_case_types)]
|
||||
pub type objc_AssociationPolicy = libc::intptr_t;
|
||||
#[allow(non_camel_case_types)]
|
||||
pub type objc_property_t = libc::intptr_t;
|
||||
pub type Protocol = libc::intptr_t;
|
||||
pub type SEL = libc::intptr_t;
|
||||
pub use objc::runtime::{BOOL, NO, YES};
|
||||
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
pub type NSInteger = libc::c_int;
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
pub type NSUInteger = libc::c_uint;
|
||||
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
pub type NSInteger = libc::c_long;
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
pub type NSUInteger = libc::c_ulong;
|
||||
pub type Class = *mut runtime::Class;
|
||||
#[allow(non_camel_case_types)]
|
||||
pub type id = *mut runtime::Object;
|
||||
pub type SEL = runtime::Sel;
|
||||
|
||||
#[allow(non_upper_case_globals)]
|
||||
pub const nil: id = 0;
|
||||
pub const nil: id = 0 as id;
|
||||
#[allow(non_upper_case_globals)]
|
||||
pub const Nil: Class = 0 as Class;
|
||||
|
||||
pub type BOOL = libc::c_schar;
|
||||
pub const NO: BOOL = 0;
|
||||
pub const YES: BOOL = 1;
|
||||
|
||||
#[allow(non_camel_case_types, missing_copy_implementations)]
|
||||
#[repr(C)]
|
||||
pub struct objc_method_description {
|
||||
name: SEL,
|
||||
types: *mut libc::c_char,
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types, missing_copy_implementations)]
|
||||
#[repr(C)]
|
||||
pub struct objc_property_attribute_t {
|
||||
name: *const libc::c_char,
|
||||
value: *const libc::c_char,
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types, missing_copy_implementations)]
|
||||
#[repr(C)]
|
||||
pub struct objc_super {
|
||||
receiver: id,
|
||||
cls: Class,
|
||||
super_class: Class,
|
||||
}
|
||||
|
||||
#[link(name = "objc")]
|
||||
extern {
|
||||
pub fn class_addProperty(cls: Class,
|
||||
name: *const libc::c_char,
|
||||
attributes: *const objc_property_attribute_t,
|
||||
attributeCount: libc::uint32_t) -> BOOL;
|
||||
pub fn class_addProtocol(cls: Class, protocol: *mut Protocol) -> BOOL;
|
||||
pub fn class_addMethod(cls: Class, name: SEL, imp: IMP, types: *const libc::c_char) -> BOOL;
|
||||
pub fn class_addIvar(cls: Class,
|
||||
name: *const libc::c_char,
|
||||
size: libc::size_t,
|
||||
alignment: libc::uint8_t,
|
||||
types: *const libc::c_char) -> BOOL;
|
||||
pub fn class_conformsToProtocol(cls: Class, protocol: *mut Protocol) -> BOOL;
|
||||
pub fn class_copyIvarList(cls: Class, outCount: *mut libc::uint32_t) -> *mut Ivar;
|
||||
pub fn class_copyMethodList(cls: Class, outCount: *mut libc::uint32_t) -> *mut Method;
|
||||
pub fn class_copyPropertyList(cls: Class,
|
||||
outCount: *mut libc::uint32_t) -> *mut objc_property_t;
|
||||
pub fn class_copyProtocolList(cls: Class, outCount: *mut libc::uint32_t) -> *mut *mut Protocol;
|
||||
pub fn class_createInstance(cls: Class, extraBytes: libc::size_t) -> id;
|
||||
pub fn class_getClassMethod(cls: Class, name: SEL) -> Method;
|
||||
pub fn class_getFutureClass(name: *const libc::c_char) -> Class;
|
||||
pub fn class_getIvarLayout(cls: Class) -> *const libc::uint8_t;
|
||||
pub fn class_getImageName(cls: Class) -> *const libc::c_char;
|
||||
pub fn class_getInstanceMethod(cls: Class, name: SEL) -> Method;
|
||||
pub fn class_getInstanceSize(cls: Class) -> libc::size_t;
|
||||
pub fn class_getInstanceVariable(cls: Class, name: *const libc::c_char) -> Ivar;
|
||||
pub fn class_getMethodImplementation(cls: Class, name: SEL) -> IMP;
|
||||
pub fn class_getMethodImplementation_stret(cls: Class, name: SEL) -> IMP;
|
||||
pub fn class_getName(cls: Class) -> *const libc::c_char;
|
||||
pub fn class_getProperty(cls: Class, name: *const libc::c_char) -> objc_property_t;
|
||||
pub fn class_getSuperclass(cls: Class) -> Class;
|
||||
pub fn class_getVersion(cls: Class) -> libc::int32_t;
|
||||
pub fn class_getWeakIvarLayout(cls: Class) -> *const libc::uint8_t;
|
||||
pub fn class_isMetaClass(cls: Class) -> BOOL;
|
||||
pub fn class_replaceMethod(cls: Class, name: SEL, imp: IMP, types: *const libc::c_char) -> IMP;
|
||||
pub fn class_replaceProperty(cls: Class,
|
||||
name: *const libc::c_char,
|
||||
attributes: *const objc_property_attribute_t,
|
||||
attributeCount: libc::uint32_t);
|
||||
pub fn class_respondsToSelector(cls: Class, sel: SEL) -> BOOL;
|
||||
pub fn class_setFutureClass(cls: Class, name: *const libc::c_char);
|
||||
pub fn class_setIvarLayout(cls: Class, layout: *const libc::uint8_t);
|
||||
pub fn class_setSuperclass(cls: Class, newSuper: Class);
|
||||
pub fn class_setWeakIvarLayout(cls: Class, layout: *const libc::uint8_t);
|
||||
pub fn class_setVersion(cls: Class, name: libc::int32_t);
|
||||
pub fn imp_getBlock(imp: IMP) -> id;
|
||||
pub fn imp_implementationWithBlock(block: id) -> IMP;
|
||||
pub fn imp_removeBlock(imp: IMP) -> BOOL;
|
||||
pub fn ivar_getName(ivar: Ivar) -> *const libc::c_char;
|
||||
pub fn ivar_getOffset(ivar: Ivar) -> libc::ptrdiff_t;
|
||||
pub fn ivar_getTypeEncoding(ivar: Ivar) -> *const libc::c_char;
|
||||
pub fn method_copyArgumentType(m: Method, index: libc::uint32_t) -> *mut libc::c_char;
|
||||
pub fn method_copyReturnType(m: Method) -> *mut libc::c_char;
|
||||
pub fn method_getArgumentType(m: Method,
|
||||
index: libc::uint32_t,
|
||||
dst: *mut libc::c_char,
|
||||
dst_len: libc::size_t);
|
||||
pub fn method_getDescription(m: Method) -> *mut objc_method_description;
|
||||
pub fn method_exchangeImplementations(m1: Method, m2: Method);
|
||||
pub fn method_getImplementation(m: Method) -> IMP;
|
||||
pub fn method_getName(m: Method) -> SEL;
|
||||
pub fn method_getNumberOfArguments(m: Method) -> libc::uint32_t;
|
||||
pub fn method_getReturnType(m: Method, dst: *mut libc::c_char, dst_len: libc::size_t);
|
||||
pub fn method_getTypeEncoding(m: Method) -> *const libc::c_char;
|
||||
pub fn method_invoke(receiver: id, m: Method, ...) -> id;
|
||||
pub fn method_invoke_stret(receiver: id, m: Method, ...);
|
||||
pub fn method_setImplementation(m: Method, imp: IMP) -> IMP;
|
||||
pub fn objc_allocateClassPair(superclass: Class,
|
||||
name: *const libc::c_char,
|
||||
extraBytes: libc::size_t) -> Class;
|
||||
pub fn objc_allocateProtocol(name: *const libc::c_char) -> *mut Protocol;
|
||||
pub fn objc_constructInstance(cls: Class, bytes: *mut libc::c_void) -> id;
|
||||
pub fn objc_copyClassList(outCount: *mut libc::uint32_t) -> *mut Class;
|
||||
pub fn objc_copyClassNamesForImage(image: *const libc::c_char,
|
||||
outCount: *mut libc::uint32_t) -> *const *const libc::c_char;
|
||||
pub fn objc_copyImageNames(outCount: *mut libc::uint32_t) -> *const *const libc::c_char;
|
||||
pub fn objc_copyProtocolList(outCount: *mut libc::uint32_t) -> *mut *mut Protocol;
|
||||
pub fn objc_destructInstance(obj: id) -> *mut libc::c_void;
|
||||
pub fn objc_disposeClassPair(cls: Class);
|
||||
pub fn objc_duplicateClass(original: Class,
|
||||
name: *const libc::c_char,
|
||||
extraBytes: libc::size_t) -> Class;
|
||||
pub fn objc_enumerationMutation(obj: id);
|
||||
pub fn objc_getAssociatedObject(object: id, key: *const libc::c_void) -> id;
|
||||
pub fn objc_getClass(name: *const libc::c_char) -> Class;
|
||||
pub fn objc_getClassList(buffer: *mut Class, bufferCount: libc::int32_t) -> libc::int32_t;
|
||||
pub fn objc_getMetaClass(name: *const libc::c_char) -> Class;
|
||||
pub fn objc_getProtocol(name: *const libc::c_char) -> *mut Protocol;
|
||||
pub fn objc_getRequiredClass(name: *const libc::c_char) -> Class;
|
||||
pub fn objc_loadWeak(location: *mut id) -> id;
|
||||
pub fn objc_storeWeak(location: *mut id, obj: id) -> id;
|
||||
pub fn objc_msgSend(target: id, selector: SEL, ...) -> id;
|
||||
pub fn objc_msgSend_ftret(target: id, selector: SEL, ...) -> libc::c_double;
|
||||
pub fn objc_msgSend_stret(target: id, selector: SEL, ...);
|
||||
pub fn objc_msgSendSuper(sup: *mut objc_super, op: SEL, ...) -> id;
|
||||
pub fn objc_msgSendSuper_stret(sup: *mut objc_super, op: SEL, ...);
|
||||
pub fn objc_registerClassPair(cls: Class);
|
||||
pub fn objc_registerProtocol(proto: *mut Protocol);
|
||||
pub fn objc_removeAssociatedObjects(object: id);
|
||||
pub fn objc_setAssociatedObject(object: id,
|
||||
key: *const libc::c_void,
|
||||
value: id,
|
||||
policy: objc_AssociationPolicy);
|
||||
pub fn objc_setEnumerationMutationHandler(handler: extern fn (id));
|
||||
pub fn object_copy(obj: id, size: libc::size_t) -> id;
|
||||
pub fn object_dispose(obj: id) -> id;
|
||||
pub fn object_getClass(obj: id) -> Class;
|
||||
pub fn object_getClassName(obj: id) -> *const libc::c_char;
|
||||
pub fn object_getIndexedIvars(obj: id) -> *mut libc::c_void;
|
||||
pub fn object_getInstanceVariable(obj: id,
|
||||
name: *const libc::c_char,
|
||||
outValue: *mut *mut libc::c_void);
|
||||
pub fn object_getIvar(obj: id, ivar: Ivar) -> id;
|
||||
pub fn object_setClass(obj: id, cls: Class) -> Class;
|
||||
pub fn object_setInstanceVariable(obj: id,
|
||||
name: *const libc::c_char,
|
||||
value: *mut libc::c_void);
|
||||
pub fn object_setIvar(obj: id, ivar: Ivar, value: id);
|
||||
pub fn protocol_addMethodDescription(proto: *mut Protocol,
|
||||
name: SEL,
|
||||
types: *const libc::c_char,
|
||||
isRequiredMethod: BOOL,
|
||||
isInstanceMethod: BOOL);
|
||||
pub fn protocol_addProperty(proto: *mut Protocol,
|
||||
name: *const libc::c_char,
|
||||
attributes: *const objc_property_attribute_t,
|
||||
attributeCount: libc::uint32_t,
|
||||
isRequiredMethod: BOOL,
|
||||
isInstanceMethod: BOOL);
|
||||
pub fn protocol_addProtocol(proto: *mut Protocol, addition: *mut Protocol);
|
||||
pub fn protocol_conformsToProtocol(proto: *mut Protocol, other: *mut Protocol) -> BOOL;
|
||||
pub fn protocol_copyMethodDescriptionList(proto: *mut Protocol,
|
||||
isRequiredMethod: BOOL,
|
||||
isInstanceMethod: BOOL,
|
||||
outCount: *mut libc::uint32_t
|
||||
) -> *mut objc_method_description;
|
||||
pub fn protocol_copyPropertyList(proto: *mut Protocol,
|
||||
outCount: *mut libc::uint32_t) -> *mut objc_property_t;
|
||||
pub fn protocol_copyProtocolList(proto: *mut Protocol,
|
||||
outCount: *mut libc::uint32_t) -> *mut *mut Protocol;
|
||||
pub fn protocol_getMethodDescription(proto: *mut Protocol,
|
||||
name: SEL,
|
||||
isRequiredMethod: BOOL,
|
||||
isInstanceMethod: BOOL) -> objc_method_description;
|
||||
pub fn protocol_getProperty(proto: *mut Protocol,
|
||||
name: *const libc::c_char,
|
||||
isRequiredMethod: BOOL,
|
||||
isInstanceMethod: BOOL) -> objc_property_t;
|
||||
pub fn protocol_getName(proto: *mut Protocol) -> *const libc::c_char;
|
||||
pub fn protocol_isEqual(proto: *mut Protocol, other: *mut Protocol) -> BOOL;
|
||||
pub fn property_copyAttributeList(property: objc_property_t,
|
||||
outCount: *mut libc::uint32_t
|
||||
) -> *mut objc_property_attribute_t;
|
||||
pub fn property_copyAttributeValue(property: objc_property_t,
|
||||
attributeName: *const libc::c_char) -> *mut libc::c_char;
|
||||
pub fn property_getAttributes(property: objc_property_t) -> *const libc::c_char;
|
||||
pub fn property_getName(property: objc_property_t) -> *const libc::c_char;
|
||||
pub fn sel_getName(sel: SEL) -> *const libc::c_char;
|
||||
pub fn sel_getUid(string: *const libc::c_char) -> SEL;
|
||||
pub fn sel_isEqual(lhs: SEL, rhs: SEL) -> BOOL;
|
||||
pub fn sel_registerName(name: *const libc::c_char) -> SEL;
|
||||
}
|
||||
|
||||
/// Returns an Objective-C message send function that returns a type `T`.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// # use cocoa::base::{class, selector, msg_send, nil};
|
||||
/// assert!(unsafe { msg_send()(class("NSObject"), selector("class")) } != nil);
|
||||
/// ```
|
||||
pub unsafe fn msg_send<T>() -> extern fn(target: id, selector: SEL, ...) -> T {
|
||||
mem::transmute(objc_msgSend)
|
||||
}
|
||||
|
||||
/// Returns an Objective-C message send function that returns a type `T`, where `T` is a struct
|
||||
/// with the attribute `#[repr(C)]`.
|
||||
pub unsafe fn msg_send_stret<T>() -> extern fn(target: id, selector: SEL, ...) -> T {
|
||||
mem::transmute(objc_msgSend_stret)
|
||||
}
|
||||
|
||||
/// A convenience method to convert the name of a class to the class object itself.
|
||||
#[inline]
|
||||
pub fn class(name: &str) -> Class {
|
||||
let name_c_str = ffi::CString::from_slice(name.as_bytes());
|
||||
unsafe {
|
||||
objc_getClass(name_c_str.as_ptr())
|
||||
mem::transmute(runtime::Class::get(name))
|
||||
}
|
||||
}
|
||||
|
||||
/// A convenience method to convert the name of a selector to the selector object.
|
||||
#[inline]
|
||||
pub fn selector(name: &str) -> SEL {
|
||||
let name_c_str = ffi::CString::from_slice(name.as_bytes());
|
||||
unsafe {
|
||||
sel_registerName(name_c_str.as_ptr())
|
||||
}
|
||||
runtime::Sel::register(name)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use libc;
|
||||
use std::ffi;
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
pub fn test_nsapp() {
|
||||
unsafe {
|
||||
let _nsApp: id = msg_send()(class("NSApplication"), selector("sharedApplication"));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_custom_obj() {
|
||||
extern fn MyObject_doSomething(this: id, _: SEL) -> id {
|
||||
println!("doSomething");
|
||||
return this;
|
||||
}
|
||||
|
||||
let ns_object = class("NSObject");
|
||||
let name_c_str = ffi::CString::from_slice("MyObject".as_bytes());
|
||||
let my_object = unsafe {
|
||||
objc_allocateClassPair(ns_object, name_c_str.as_ptr(), 0 as libc::size_t)
|
||||
};
|
||||
|
||||
let doSomething = selector("doSomething");
|
||||
let types_c_str = ffi::CString::from_slice("@@:".as_bytes());
|
||||
unsafe {
|
||||
let _ = class_addMethod(my_object, doSomething, MyObject_doSomething,
|
||||
types_c_str.as_ptr());
|
||||
|
||||
objc_registerClassPair(my_object);
|
||||
|
||||
let mut obj: id = msg_send()(my_object, selector("alloc"));
|
||||
obj = msg_send()(obj, selector("init"));
|
||||
let _: () = msg_send()(obj, selector("doSomething"));
|
||||
let _nsApp: id = msg_send![class("NSApplication"), sharedApplication];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,621 @@
|
||||
// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![allow(non_upper_case_globals)]
|
||||
|
||||
use std::mem;
|
||||
use std::ptr;
|
||||
use base::{id, class, BOOL, SEL, nil};
|
||||
use block::Block;
|
||||
use core_graphics::base::CGFloat;
|
||||
use core_graphics::geometry::CGRect;
|
||||
use libc;
|
||||
use objc;
|
||||
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
pub type NSInteger = libc::c_int;
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
pub type NSUInteger = libc::c_uint;
|
||||
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
pub type NSInteger = libc::c_long;
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
pub type NSUInteger = libc::c_ulong;
|
||||
|
||||
const UTF8_ENCODING: usize = 4;
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct NSPoint {
|
||||
pub x: f64,
|
||||
pub y: f64,
|
||||
}
|
||||
|
||||
impl NSPoint {
|
||||
#[inline]
|
||||
pub fn new(x: f64, y: f64) -> NSPoint {
|
||||
NSPoint {
|
||||
x: x,
|
||||
y: y,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl objc::Encode for NSPoint {
|
||||
fn encode() -> objc::Encoding {
|
||||
let encoding = format!("{{CGPoint={}{}}}",
|
||||
f64::encode().as_str(),
|
||||
f64::encode().as_str());
|
||||
unsafe { objc::Encoding::from_str(&encoding) }
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct NSSize {
|
||||
pub width: f64,
|
||||
pub height: f64,
|
||||
}
|
||||
|
||||
impl NSSize {
|
||||
#[inline]
|
||||
pub fn new(width: f64, height: f64) -> NSSize {
|
||||
NSSize {
|
||||
width: width,
|
||||
height: height,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl objc::Encode for NSSize {
|
||||
fn encode() -> objc::Encoding {
|
||||
let encoding = format!("{{CGSize={}{}}}",
|
||||
f64::encode().as_str(),
|
||||
f64::encode().as_str());
|
||||
unsafe { objc::Encoding::from_str(&encoding) }
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct NSRect {
|
||||
pub origin: NSPoint,
|
||||
pub size: NSSize,
|
||||
}
|
||||
|
||||
impl NSRect {
|
||||
#[inline]
|
||||
pub fn new(origin: NSPoint, size: NSSize) -> NSRect {
|
||||
NSRect {
|
||||
origin: origin,
|
||||
size: size
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn as_CGRect(&self) -> &CGRect {
|
||||
unsafe {
|
||||
mem::transmute::<&NSRect, &CGRect>(self)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn inset(&self, x: CGFloat, y: CGFloat) -> NSRect {
|
||||
unsafe {
|
||||
NSInsetRect(*self, x, y)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct NSRange {
|
||||
pub location: NSUInteger,
|
||||
pub length: NSUInteger,
|
||||
}
|
||||
|
||||
impl NSRange {
|
||||
#[inline]
|
||||
pub fn new(location: NSUInteger, length: NSUInteger) -> NSRange {
|
||||
NSRange {
|
||||
location: location,
|
||||
length: length
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl objc::Encode for NSRect {
|
||||
fn encode() -> objc::Encoding {
|
||||
let encoding = format!("{{CGRect={}{}}}",
|
||||
NSPoint::encode().as_str(),
|
||||
NSSize::encode().as_str());
|
||||
unsafe { objc::Encoding::from_str(&encoding) }
|
||||
}
|
||||
}
|
||||
|
||||
// Same as CGRectEdge
|
||||
#[repr(u32)]
|
||||
pub enum NSRectEdge {
|
||||
NSRectMinXEdge,
|
||||
NSRectMinYEdge,
|
||||
NSRectMaxXEdge,
|
||||
NSRectMaxYEdge,
|
||||
}
|
||||
|
||||
#[link(name = "Foundation", kind = "framework")]
|
||||
extern {
|
||||
pub static NSDefaultRunLoopMode: id;
|
||||
}
|
||||
|
||||
pub trait NSAutoreleasePool {
|
||||
unsafe fn new(_: Self) -> id {
|
||||
msg_send![class("NSAutoreleasePool"), new]
|
||||
}
|
||||
|
||||
unsafe fn autorelease(self) -> Self;
|
||||
unsafe fn drain(self);
|
||||
}
|
||||
|
||||
impl NSAutoreleasePool for id {
|
||||
unsafe fn autorelease(self) -> id {
|
||||
msg_send![self, autorelease]
|
||||
}
|
||||
|
||||
unsafe fn drain(self) {
|
||||
msg_send![self, drain]
|
||||
}
|
||||
}
|
||||
|
||||
pub trait NSProcessInfo {
|
||||
unsafe fn processInfo(_: Self) -> id {
|
||||
msg_send![class("NSProcessInfo"), processInfo]
|
||||
}
|
||||
|
||||
unsafe fn processName(self) -> id;
|
||||
}
|
||||
|
||||
impl NSProcessInfo for id {
|
||||
unsafe fn processName(self) -> id {
|
||||
msg_send![self, processName]
|
||||
}
|
||||
}
|
||||
|
||||
pub type NSTimeInterval = libc::c_double;
|
||||
|
||||
pub trait NSValue {
|
||||
unsafe fn valueWithPoint(_: Self, point: NSPoint) -> id {
|
||||
msg_send![class("NSValue"), valueWithPoint:point]
|
||||
}
|
||||
|
||||
unsafe fn valueWithSize(_: Self, size: NSSize) -> id {
|
||||
msg_send![class("NSValue"), valueWithSize:size]
|
||||
}
|
||||
}
|
||||
|
||||
impl NSValue for id {
|
||||
}
|
||||
|
||||
pub trait NSArray {
|
||||
unsafe fn array(_: Self) -> id {
|
||||
msg_send![class("NSArray"), array]
|
||||
}
|
||||
|
||||
unsafe fn arrayWithObjects(_: Self, objects: &[id]) -> id {
|
||||
msg_send![class("NSArray"), arrayWithObjects:objects.as_ptr()
|
||||
count:objects.len()]
|
||||
}
|
||||
|
||||
unsafe fn arrayWithObject(_: Self, object: id) -> id {
|
||||
msg_send![class("NSArray"), arrayWithObject:object]
|
||||
}
|
||||
|
||||
unsafe fn arrayByAddingObjectFromArray(self, object: id) -> id;
|
||||
unsafe fn arrayByAddingObjectsFromArray(self, objects: id) -> id;
|
||||
}
|
||||
|
||||
impl NSArray for id {
|
||||
unsafe fn arrayByAddingObjectFromArray(self, object: id) -> id {
|
||||
msg_send![self, arrayByAddingObjectFromArray:object]
|
||||
}
|
||||
|
||||
unsafe fn arrayByAddingObjectsFromArray(self, objects: id) -> id {
|
||||
msg_send![self, arrayByAddingObjectsFromArray:objects]
|
||||
}
|
||||
}
|
||||
|
||||
pub trait NSString {
|
||||
unsafe fn alloc(_: Self) -> id {
|
||||
msg_send![class("NSString"), alloc]
|
||||
}
|
||||
|
||||
unsafe fn stringByAppendingString_(self, other: id) -> id;
|
||||
unsafe fn init_str(self, string: &str) -> Self;
|
||||
unsafe fn UTF8String(self) -> *const libc::c_char;
|
||||
unsafe fn len(self) -> usize;
|
||||
unsafe fn isEqualToString(self, &str) -> bool;
|
||||
}
|
||||
|
||||
impl NSString for id {
|
||||
unsafe fn isEqualToString(self, other: &str) -> bool {
|
||||
let other = NSString::alloc(nil).init_str(other);
|
||||
let rv: BOOL = msg_send![self, isEqualToString:other];
|
||||
rv != 0
|
||||
}
|
||||
|
||||
unsafe fn stringByAppendingString_(self, other: id) -> id {
|
||||
msg_send![self, stringByAppendingString:other]
|
||||
}
|
||||
|
||||
unsafe fn init_str(self, string: &str) -> id {
|
||||
return msg_send![self,
|
||||
initWithBytes:string.as_ptr()
|
||||
length:string.len()
|
||||
encoding:UTF8_ENCODING as id];
|
||||
}
|
||||
|
||||
unsafe fn len(self) -> usize {
|
||||
msg_send![self, lengthOfBytesUsingEncoding:UTF8_ENCODING]
|
||||
}
|
||||
|
||||
unsafe fn UTF8String(self) -> *const libc::c_char {
|
||||
msg_send![self, UTF8String]
|
||||
}
|
||||
}
|
||||
|
||||
pub trait NSDate {
|
||||
unsafe fn distantPast(_: Self) -> id {
|
||||
msg_send![class("NSDate"), distantPast]
|
||||
}
|
||||
|
||||
unsafe fn distantFuture(_: Self) -> id {
|
||||
msg_send![class("NSDate"), distantFuture]
|
||||
}
|
||||
}
|
||||
|
||||
impl NSDate for id {
|
||||
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
struct NSFastEnumerationState {
|
||||
pub state: libc::c_ulong,
|
||||
pub items_ptr: *mut id,
|
||||
pub mutations_ptr: *mut libc::c_ulong,
|
||||
pub extra: [libc::c_ulong; 5]
|
||||
}
|
||||
|
||||
const NS_FAST_ENUM_BUF_SIZE: usize = 16;
|
||||
|
||||
pub struct NSFastIterator {
|
||||
state: NSFastEnumerationState,
|
||||
buffer: [id; NS_FAST_ENUM_BUF_SIZE],
|
||||
mut_val: Option<libc::c_ulong>,
|
||||
len: usize,
|
||||
idx: usize,
|
||||
object: id
|
||||
}
|
||||
|
||||
impl Iterator for NSFastIterator {
|
||||
type Item = id;
|
||||
|
||||
fn next(&mut self) -> Option<id> {
|
||||
if self.idx >= self.len {
|
||||
self.len = unsafe {
|
||||
msg_send![self.object, countByEnumeratingWithState:&mut self.state objects:self.buffer.as_mut_ptr() count:NS_FAST_ENUM_BUF_SIZE]
|
||||
};
|
||||
self.idx = 0;
|
||||
}
|
||||
|
||||
let new_mut = unsafe {
|
||||
*self.state.mutations_ptr
|
||||
};
|
||||
|
||||
if let Some(old_mut) = self.mut_val {
|
||||
assert!(old_mut == new_mut, "The collection was mutated while being enumerated");
|
||||
}
|
||||
|
||||
if self.idx < self.len {
|
||||
let object = unsafe {
|
||||
*self.state.items_ptr.offset(self.idx as isize)
|
||||
};
|
||||
self.mut_val = Some(new_mut);
|
||||
self.idx += 1;
|
||||
Some(object)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait NSFastEnumeration {
|
||||
unsafe fn iter(self) -> NSFastIterator;
|
||||
}
|
||||
|
||||
impl NSFastEnumeration for id {
|
||||
unsafe fn iter(self) -> NSFastIterator {
|
||||
NSFastIterator {
|
||||
state: NSFastEnumerationState {
|
||||
state: 0,
|
||||
items_ptr: ptr::null_mut(),
|
||||
mutations_ptr: ptr::null_mut(),
|
||||
extra: [0; 5]
|
||||
},
|
||||
buffer: [nil; NS_FAST_ENUM_BUF_SIZE],
|
||||
mut_val: None,
|
||||
len: 0,
|
||||
idx: 0,
|
||||
object: self
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[link(name = "Foundation", kind = "framework")]
|
||||
extern {
|
||||
fn NSInsetRect(rect: NSRect, x: CGFloat, y: CGFloat) -> NSRect;
|
||||
}
|
||||
|
||||
pub trait NSRunLoop {
|
||||
unsafe fn currentRunLoop() -> Self;
|
||||
|
||||
unsafe fn performSelector_target_argument_order_modes_(self,
|
||||
aSelector: SEL,
|
||||
target: id,
|
||||
anArgument: id,
|
||||
order: NSUInteger,
|
||||
modes: id);
|
||||
}
|
||||
|
||||
impl NSRunLoop for id {
|
||||
unsafe fn currentRunLoop() -> id {
|
||||
msg_send![class("NSRunLoop"), currentRunLoop]
|
||||
}
|
||||
|
||||
unsafe fn performSelector_target_argument_order_modes_(self,
|
||||
aSelector: SEL,
|
||||
target: id,
|
||||
anArgument: id,
|
||||
order: NSUInteger,
|
||||
modes: id) {
|
||||
msg_send![self, performSelector:aSelector
|
||||
target:target
|
||||
argument:anArgument
|
||||
order:order
|
||||
modes:modes]
|
||||
}
|
||||
}
|
||||
|
||||
pub trait NSData {
|
||||
unsafe fn data(_: Self) -> id {
|
||||
msg_send![class("NSData"), data]
|
||||
}
|
||||
|
||||
unsafe fn dataWithBytes_length_(_: Self, bytes: *const libc::c_void, length: NSUInteger) -> id {
|
||||
msg_send![class("NSData"), dataWithBytes:bytes length:length]
|
||||
}
|
||||
|
||||
unsafe fn dataWithBytesNoCopy_length_(_: Self, bytes: *const libc::c_void, length: NSUInteger) -> id {
|
||||
msg_send![class("NSData"), dataWithBytesNoCopy:bytes length:length]
|
||||
}
|
||||
|
||||
unsafe fn dataWithBytesNoCopy_length_freeWhenDone_(_: Self, bytes: *const libc::c_void,
|
||||
length: NSUInteger, freeWhenDone: BOOL) -> id {
|
||||
msg_send![class("NSData"), dataWithBytesNoCopy:bytes length:length freeWhenDone:freeWhenDone]
|
||||
}
|
||||
|
||||
unsafe fn dataWithContentsOfFile_(_: Self, path: id) -> id {
|
||||
msg_send![class("NSData"), dataWithContentsOfFile:path]
|
||||
}
|
||||
|
||||
unsafe fn dataWithContentsOfFile_options_error_(_: Self, path: id, mask: NSDataReadingOptions,
|
||||
errorPtr: *mut id) -> id {
|
||||
msg_send![class("NSData"), dataWithContentsOfFile:path options:mask error:errorPtr]
|
||||
}
|
||||
|
||||
unsafe fn dataWithContentsOfURL_(_: Self, aURL: id) -> id {
|
||||
msg_send![class("NSData"), dataWithContentsOfURL:aURL]
|
||||
}
|
||||
|
||||
unsafe fn dataWithContentsOfURL_options_error_(_: Self, aURL: id, mask: NSDataReadingOptions,
|
||||
errorPtr: *mut id) -> id {
|
||||
msg_send![class("NSData"), dataWithContentsOfURL:aURL options:mask error:errorPtr]
|
||||
}
|
||||
|
||||
unsafe fn dataWithData_(_: Self, aData: id) -> id {
|
||||
msg_send![class("NSData"), dataWithData:aData]
|
||||
}
|
||||
|
||||
unsafe fn initWithBase64EncodedData_options_(self, base64Data: id, options: NSDataBase64DecodingOptions)
|
||||
-> id;
|
||||
unsafe fn initWithBase64EncodedString_options_(self, base64String: id, options: NSDataBase64DecodingOptions)
|
||||
-> id;
|
||||
unsafe fn initWithBytes_length_(self, bytes: *const libc::c_void, length: NSUInteger) -> id;
|
||||
unsafe fn initWithBytesNoCopy_length_(self, bytes: *const libc::c_void, length: NSUInteger) -> id;
|
||||
unsafe fn initWithBytesNoCopy_length_deallocator_(self, bytes: *const libc::c_void, length: NSUInteger,
|
||||
deallocator: *mut Block<(*const libc::c_void, NSUInteger), ()>)
|
||||
-> id;
|
||||
unsafe fn initWithBytesNoCopy_length_freeWhenDone_(self, bytes: *const libc::c_void,
|
||||
length: NSUInteger, freeWhenDone: BOOL) -> id;
|
||||
unsafe fn initWithContentsOfFile_(self, path: id) -> id;
|
||||
unsafe fn initWithContentsOfFile_options_error(self, path: id, mask: NSDataReadingOptions, errorPtr: *mut id)
|
||||
-> id;
|
||||
unsafe fn initWithContentsOfURL_(self, aURL: id) -> id;
|
||||
unsafe fn initWithContentsOfURL_options_error_(self, aURL: id, mask: NSDataReadingOptions, errorPtr: *mut id)
|
||||
-> id;
|
||||
unsafe fn initWithData_(self, data: id) -> id;
|
||||
|
||||
unsafe fn bytes(self) -> *const libc::c_void;
|
||||
unsafe fn description(self) -> id;
|
||||
unsafe fn enumerateByteRangesUsingBlock_(self, block: *mut Block<(*const libc::c_void, NSRange, *mut BOOL), ()>);
|
||||
unsafe fn getBytes_length_(self, buffer: *mut libc::c_void, length: NSUInteger);
|
||||
unsafe fn getBytes_range_(self, buffer: *mut libc::c_void, range: NSRange);
|
||||
unsafe fn subdataWithRange_(self, range: NSRange) -> id;
|
||||
unsafe fn rangeOfData_options_range_(self, dataToFind: id, options: NSDataSearchOptions, searchRange: NSRange)
|
||||
-> NSRange;
|
||||
|
||||
unsafe fn base64EncodedDataWithOptions_(self, options: NSDataBase64EncodingOptions) -> id;
|
||||
unsafe fn base64EncodedStringWithOptions_(self, options: NSDataBase64EncodingOptions) -> id;
|
||||
|
||||
unsafe fn isEqualToData_(self, otherData: id) -> id;
|
||||
unsafe fn length(self) -> NSUInteger;
|
||||
|
||||
unsafe fn writeToFile_atomically_(self, path: id, atomically: BOOL) -> BOOL;
|
||||
unsafe fn writeToFile_options_error_(self, path: id, mask: NSDataWritingOptions, errorPtr: *mut id) -> BOOL;
|
||||
unsafe fn writeToURL_atomically_(self, aURL: id, atomically: BOOL) -> BOOL;
|
||||
unsafe fn writeToURL_options_error_(self, aURL: id, mask: NSDataWritingOptions, errorPtr: *mut id) -> BOOL;
|
||||
}
|
||||
|
||||
impl NSData for id {
|
||||
unsafe fn initWithBase64EncodedData_options_(self, base64Data: id, options: NSDataBase64DecodingOptions)
|
||||
-> id {
|
||||
msg_send![self, initWithBase64EncodedData:base64Data options:options]
|
||||
}
|
||||
|
||||
unsafe fn initWithBase64EncodedString_options_(self, base64String: id, options: NSDataBase64DecodingOptions)
|
||||
-> id {
|
||||
msg_send![self, initWithBase64EncodedString:base64String options:options]
|
||||
}
|
||||
|
||||
unsafe fn initWithBytes_length_(self, bytes: *const libc::c_void, length: NSUInteger) -> id {
|
||||
msg_send![self,initWithBytes:bytes length:length]
|
||||
}
|
||||
|
||||
unsafe fn initWithBytesNoCopy_length_(self, bytes: *const libc::c_void, length: NSUInteger) -> id {
|
||||
msg_send![self, initWithBytesNoCopy:bytes length:length]
|
||||
}
|
||||
|
||||
unsafe fn initWithBytesNoCopy_length_deallocator_(self, bytes: *const libc::c_void, length: NSUInteger,
|
||||
deallocator: *mut Block<(*const libc::c_void, NSUInteger), ()>)
|
||||
-> id {
|
||||
msg_send![self, initWithBytesNoCopy:bytes length:length deallocator:deallocator]
|
||||
}
|
||||
|
||||
unsafe fn initWithBytesNoCopy_length_freeWhenDone_(self, bytes: *const libc::c_void,
|
||||
length: NSUInteger, freeWhenDone: BOOL) -> id {
|
||||
msg_send![self, initWithBytesNoCopy:bytes length:length freeWhenDone:freeWhenDone]
|
||||
}
|
||||
|
||||
unsafe fn initWithContentsOfFile_(self, path: id) -> id {
|
||||
msg_send![self, initWithContentsOfFile:path]
|
||||
}
|
||||
|
||||
unsafe fn initWithContentsOfFile_options_error(self, path: id, mask: NSDataReadingOptions, errorPtr: *mut id)
|
||||
-> id {
|
||||
msg_send![self, initWithContentsOfFile:path options:mask error:errorPtr]
|
||||
}
|
||||
|
||||
unsafe fn initWithContentsOfURL_(self, aURL: id) -> id {
|
||||
msg_send![self, initWithContentsOfURL:aURL]
|
||||
}
|
||||
|
||||
unsafe fn initWithContentsOfURL_options_error_(self, aURL: id, mask: NSDataReadingOptions, errorPtr: *mut id)
|
||||
-> id {
|
||||
msg_send![self, initWithContentsOfURL:aURL options:mask error:errorPtr]
|
||||
}
|
||||
|
||||
unsafe fn initWithData_(self, data: id) -> id {
|
||||
msg_send![self, initWithData:data]
|
||||
}
|
||||
|
||||
unsafe fn bytes(self) -> *const libc::c_void {
|
||||
msg_send![self, bytes]
|
||||
}
|
||||
|
||||
unsafe fn description(self) -> id {
|
||||
msg_send![self, description]
|
||||
}
|
||||
|
||||
unsafe fn enumerateByteRangesUsingBlock_(self, block: *mut Block<(*const libc::c_void, NSRange, *mut BOOL), ()>) {
|
||||
msg_send![self, enumerateByteRangesUsingBlock:block]
|
||||
}
|
||||
|
||||
unsafe fn getBytes_length_(self, buffer: *mut libc::c_void, length: NSUInteger) {
|
||||
msg_send![self, getBytes:buffer length:length]
|
||||
}
|
||||
|
||||
unsafe fn getBytes_range_(self, buffer: *mut libc::c_void, range: NSRange) {
|
||||
msg_send![self, getBytes:buffer range:range]
|
||||
}
|
||||
|
||||
unsafe fn subdataWithRange_(self, range: NSRange) -> id {
|
||||
msg_send![self, subdataWithRange:range]
|
||||
}
|
||||
|
||||
unsafe fn rangeOfData_options_range_(self, dataToFind: id, options: NSDataSearchOptions, searchRange: NSRange)
|
||||
-> NSRange {
|
||||
msg_send![self, rangeOfData:dataToFind options:options range:searchRange]
|
||||
}
|
||||
|
||||
unsafe fn base64EncodedDataWithOptions_(self, options: NSDataBase64EncodingOptions) -> id {
|
||||
msg_send![self, base64EncodedDataWithOptions:options]
|
||||
}
|
||||
|
||||
unsafe fn base64EncodedStringWithOptions_(self, options: NSDataBase64EncodingOptions) -> id {
|
||||
msg_send![self, base64EncodedStringWithOptions:options]
|
||||
}
|
||||
|
||||
unsafe fn isEqualToData_(self, otherData: id) -> id {
|
||||
msg_send![self, isEqualToData:otherData]
|
||||
}
|
||||
|
||||
unsafe fn length(self) -> NSUInteger {
|
||||
msg_send![self, length]
|
||||
}
|
||||
|
||||
unsafe fn writeToFile_atomically_(self, path: id, atomically: BOOL) -> BOOL {
|
||||
msg_send![self, writeToFile:path atomically:atomically]
|
||||
}
|
||||
|
||||
unsafe fn writeToFile_options_error_(self, path: id, mask: NSDataWritingOptions, errorPtr: *mut id) -> BOOL {
|
||||
msg_send![self, writeToFile:path options:mask error:errorPtr]
|
||||
}
|
||||
|
||||
unsafe fn writeToURL_atomically_(self, aURL: id, atomically: BOOL) -> BOOL {
|
||||
msg_send![self, writeToURL:aURL atomically:atomically]
|
||||
}
|
||||
|
||||
unsafe fn writeToURL_options_error_(self, aURL: id, mask: NSDataWritingOptions, errorPtr: *mut id) -> BOOL {
|
||||
msg_send![self, writeToURL:aURL options:mask error:errorPtr]
|
||||
}
|
||||
}
|
||||
|
||||
bitflags! {
|
||||
pub flags NSDataReadingOptions: libc::c_ulonglong {
|
||||
const NSDataReadingMappedIfSafe = 1 << 0,
|
||||
const NSDataReadingUncached = 1 << 1,
|
||||
const NSDataReadingMappedAlways = 1 << 3
|
||||
}
|
||||
}
|
||||
|
||||
bitflags! {
|
||||
pub flags NSDataBase64EncodingOptions: libc::c_ulonglong {
|
||||
const NSDataBase64Encoding64CharacterLineLength = 1 << 0,
|
||||
const NSDataBase64Encoding76CharacterLineLength = 1 << 1,
|
||||
const NSDataBase64EncodingEndLineWithCarriageReturn = 1 << 4,
|
||||
const NSDataBase64EncodingEndLineWithLineFeed = 1 << 5
|
||||
}
|
||||
}
|
||||
|
||||
bitflags! {
|
||||
pub flags NSDataBase64DecodingOptions: libc::c_ulonglong {
|
||||
const NSDataBase64DecodingIgnoreUnknownCharacters = 1 << 0
|
||||
}
|
||||
}
|
||||
|
||||
bitflags! {
|
||||
pub flags NSDataWritingOptions: libc::c_ulonglong {
|
||||
const NSDataWritingAtomic = 1 << 0,
|
||||
const NSDataWritingWithoutOverwriting = 1 << 1
|
||||
}
|
||||
}
|
||||
|
||||
bitflags! {
|
||||
pub flags NSDataSearchOptions: libc::c_ulonglong {
|
||||
const NSDataSearchBackwards = 1 << 0,
|
||||
const NSDataSearchAnchored = 1 << 1
|
||||
}
|
||||
}
|
||||
+6
-4
@@ -10,14 +10,16 @@
|
||||
#![crate_name = "cocoa"]
|
||||
#![crate_type = "rlib"]
|
||||
|
||||
#![allow(missing_copy_implementations, non_snake_case)]
|
||||
#![feature(std_misc, hash)]
|
||||
#![allow(non_snake_case)]
|
||||
|
||||
extern crate block;
|
||||
#[macro_use]
|
||||
extern crate bitflags;
|
||||
extern crate libc;
|
||||
extern crate core_graphics;
|
||||
#[macro_use]
|
||||
extern crate objc;
|
||||
|
||||
#[cfg(target_os="macos")]
|
||||
pub mod appkit;
|
||||
#[cfg(target_os="macos")]
|
||||
pub mod base;
|
||||
pub mod foundation;
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
#[macro_use]
|
||||
extern crate objc;
|
||||
extern crate cocoa;
|
||||
|
||||
#[cfg(test)]
|
||||
mod foundation {
|
||||
mod nsstring {
|
||||
use cocoa::foundation::{NSString};
|
||||
use cocoa::base::{nil};
|
||||
use std::slice;
|
||||
use std::str;
|
||||
|
||||
#[test]
|
||||
fn test_utf8() {
|
||||
let expected = "Iñtërnâtiônàlizætiøn";
|
||||
unsafe {
|
||||
let built = NSString::alloc(nil).init_str(expected);
|
||||
let bytes = built.UTF8String() as *const u8;
|
||||
let objc_string = str::from_utf8(slice::from_raw_parts(bytes, built.len())).unwrap();
|
||||
assert!(objc_string.len() == expected.len());
|
||||
assert!(objc_string == expected);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_string() {
|
||||
let expected = "Hello World!";
|
||||
unsafe {
|
||||
let built = NSString::alloc(nil).init_str(expected);
|
||||
let bytes = built.UTF8String() as *const u8;
|
||||
let objc_string = str::from_utf8(slice::from_raw_parts(bytes, built.len())).unwrap();
|
||||
assert!(objc_string.len() == expected.len());
|
||||
assert!(objc_string == expected);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_length() {
|
||||
let expected = "Hello!";
|
||||
unsafe {
|
||||
let built = NSString::alloc(nil).init_str(expected);
|
||||
assert!(built.len() == expected.len());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_append_by_appending_string() {
|
||||
let initial_str = "Iñtërnâtiônàlizætiøn";
|
||||
let to_append = "_more_strings";
|
||||
let expected = concat!("Iñtërnâtiônàlizætiøn", "_more_strings");
|
||||
unsafe {
|
||||
let built = NSString::alloc(nil).init_str(initial_str);
|
||||
let built_to_append = NSString::alloc(nil).init_str(to_append);
|
||||
let append_string = built.stringByAppendingString_(built_to_append);
|
||||
let bytes = append_string.UTF8String() as *const u8;
|
||||
let objc_string = str::from_utf8(slice::from_raw_parts(bytes, append_string.len())).unwrap();
|
||||
assert!(objc_string == expected);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod nsfastenumeration {
|
||||
use std::str;
|
||||
use std::slice;
|
||||
use cocoa::foundation::{NSString, NSFastEnumeration};
|
||||
use cocoa::base::{id, nil};
|
||||
|
||||
#[test]
|
||||
fn test_iter() {
|
||||
unsafe {
|
||||
let string = NSString::alloc(nil).init_str("this is a test string");
|
||||
let separator = NSString::alloc(nil).init_str(" ");
|
||||
let components: id = msg_send![string, componentsSeparatedByString:separator];
|
||||
|
||||
let combined = components.iter()
|
||||
.map(|s| {
|
||||
let bytes = s.UTF8String() as *const u8;
|
||||
str::from_utf8(slice::from_raw_parts(bytes, s.len())).unwrap()
|
||||
})
|
||||
.fold(String::new(), |mut acc, s| { acc.push_str(s); acc });
|
||||
|
||||
assert_eq!(combined, "thisisateststring");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_mutation() {
|
||||
unsafe {
|
||||
let string = NSString::alloc(nil).init_str("this is a test string");
|
||||
let separator = NSString::alloc(nil).init_str(" ");
|
||||
let components: id = msg_send![string, componentsSeparatedByString:separator];
|
||||
let mut_components: id = msg_send![components, mutableCopy];
|
||||
let mut iter = mut_components.iter();
|
||||
iter.next();
|
||||
msg_send![mut_components, removeObjectAtIndex:1];
|
||||
iter.next();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user