Cleaning up

This commit is contained in:
Ryan McGrath 2020-03-31 17:38:47 -07:00
parent f4ca9770e1
commit 8c39ea6f94
No known key found for this signature in database
GPG key ID: 811674B62B666830
8 changed files with 101 additions and 34 deletions

View file

@ -38,7 +38,7 @@ use objc::{class, msg_send, sel, sel_impl};
use objc::runtime::Object;
use objc_id::Id;
use crate::foundation::{id, nil, YES, BOOL, NSData, NSInteger, NSString, NSDictionary, NSNumber};
use crate::foundation::{id, nil, YES, NO, BOOL, NSData, NSString, NSDictionary, NSNumber};
mod value;
pub use value::Value;
@ -213,4 +213,49 @@ impl UserDefaults {
None
}
/// Returns a boolean value if the object stored for the specified key is managed by an
/// administrator. This is rarely used - mostly in managed environments, e.g a classroom.
///
/// For managed keys, the application should disable any user interface that allows the
/// user to modify the value of key.
///
/// ```rust
/// use cacao::defaults::{UserDefaults, Value};
///
/// let mut defaults = UserDefaults::standard();
/// defaults.insert("test", Value::string("value"));
///
/// let value = defaults.is_forced_for_key("test");
/// assert_eq!(value, false);
/// ```
pub fn is_forced_for_key<K: AsRef<str>>(&self, key: K) -> bool {
let result: BOOL = unsafe {
let key = NSString::new(key.as_ref());
msg_send![&*self.0, objectIsForcedForKey:key.into_inner()]
};
match result {
YES => true,
NO => false,
_ => unreachable!()
}
}
/// Blocks for any asynchronous updates to the defaults database and returns.
///
/// This method is legacy, likely unnecessary and shouldn't be used unless you know exactly why
/// you need it... and even then, you should double check it.
/// ```rust
/// use cacao::defaults::{UserDefaults, Value};
///
/// let mut defaults = UserDefaults::standard();
/// defaults.insert("test", Value::string("value"));
/// defaults.synchronize();
/// ```
pub fn synchronize(&self) {
unsafe {
let _: () = msg_send![&*self.0, synchronize];
}
}
}

View file

@ -1,9 +1,6 @@
use std::collections::HashMap;
use objc::{class, msg_send, sel, sel_impl};
use objc_id::Id;
use crate::foundation::{id, YES, NO, NSData, NSInteger, NSDictionary, NSString};
use crate::foundation::{id, NSData, NSDictionary, NSString, NSNumber};
/// Represents a Value that can be stored or queried with `UserDefaults`.
///
@ -138,21 +135,15 @@ impl From<Value> for id {
// These currently work, but may not be exhaustive and should be looked over past the preview
// period.
fn from(value: Value) -> Self {
unsafe {
match value {
Value::Bool(b) => msg_send![class!(NSNumber), numberWithBool:match b {
true => YES,
false => NO
}],
Value::Bool(b) => NSNumber::bool(b).into_inner(),
Value::String(s) => NSString::new(&s).into_inner(),
Value::Float(f) => msg_send![class!(NSNumber), numberWithDouble:f],
Value::Integer(i) => msg_send![class!(NSNumber), numberWithInteger:i as NSInteger],
Value::Float(f) => NSNumber::float(f).into_inner(),
Value::Integer(i) => NSNumber::integer(i).into_inner(),
Value::Data(data) => NSData::new(data).into_inner()
}
}
}
}
impl<K> From<HashMap<K, Value>> for NSDictionary
where
@ -160,16 +151,13 @@ where
{
/// Translates a `HashMap` of `Value`s into an `NSDictionary`.
fn from(map: HashMap<K, Value>) -> Self {
NSDictionary(unsafe {
let dictionary: id = msg_send![class!(NSMutableDictionary), new];
let mut dictionary = NSDictionary::new();
for (key, value) in map.into_iter() {
let k = NSString::new(key.as_ref());
let v: id = value.into();
let _: () = msg_send![dictionary, setObject:v forKey:k];
dictionary.insert(k, value.into());
}
Id::from_ptr(dictionary)
})
dictionary
}
}

View file

@ -1,4 +1,6 @@
//! A wrapper type for `NSArray`. This is abstracted out as we need to use `NSArray` in a ton of
//! A wrapper type for `NSArray`.
//!
//! This is abstracted out as we need to use `NSArray` in a ton of
//! instances in this framework, and down the road I'd like to investigate using `CFArray` instead
//! of `NSArray` (i.e, if the ObjC runtime is ever pulled or something - perhaps those types would
//! stick around).

View file

@ -5,7 +5,7 @@ use objc::{class, msg_send, sel, sel_impl};
use objc::runtime::Object;
use objc_id::Id;
use crate::foundation::id;
use crate::foundation::{id, NSString};
/// A wrapper for `NSDictionary`. Behind the scenes we actually wrap `NSMutableDictionary`, and
/// rely on Rust doing the usual borrow-checking guards that it does so well.
@ -25,6 +25,12 @@ impl NSDictionary {
})
}
pub fn insert(&mut self, key: NSString, object: id) {
unsafe {
let _: () = msg_send![&*self.0, setObject:object forKey:key.into_inner()];
}
}
pub fn into_inner(mut self) -> id {
&mut *self.0
}

View file

@ -21,8 +21,7 @@ impl NSNumber {
NSNumber(unsafe {
Id::from_ptr(msg_send![class!(NSNumber), numberWithBool:match value {
true => YES,
false => NO,
_ => unreachable!()
false => NO
}])
})
}

View file

@ -75,7 +75,6 @@ pub use url;
#[cfg(feature = "macos")]
pub mod macos;
pub mod alert;
pub mod button;
#[cfg(feature = "cloudkit")]

View file

@ -1,5 +1,28 @@
//! A wrapper for `NSAlert`. Currently doesn't cover everything possible for this class, as it was
//! built primarily for debugging uses. Feel free to extend via pull requests or something.
//! A wrapper for `NSAlert`.
//!
//! This is housed inside `macos` as it's a useful tool for a few cases, but it doesn't match the
//! iOS API, so we make no guarantees about it being a universal control. In general this also
//! doesn't produce an amazing user experience, and you may want to shy away from using it.
//!
//! If you want to show a complex view in an alert-esque fashion, you may consider looking at
//! `Sheet`.
//!
//! ```rust
//! use cacao::macos::{App, AppDelegate, Alert};
//!
//! #[derive(Default)]
//! struct ExampleApp;
//!
//! impl AppDelegate {
//! fn did_finish_launching(&self) {
//!
//! }
//! }
//!
//! fn main() {
//! App::new("com.alert.example", ExampleApp::default()).run()
//! }
//! ```
use objc_id::Id;
use objc::runtime::Object;

View file

@ -15,7 +15,12 @@
//! of your app as a cross platform codebase, with the initial 10% being scaffolding code for the
//! platform (e.g, NSApplication vs UIApplication lifecycle).
pub mod app;
mod alert;
pub use alert::Alert;
mod app;
pub use app::*;
pub mod menu;
pub mod printing;
pub mod toolbar;