use crate::objc;
use core::ffi::c_void;
fn standard() -> *mut c_void {
unsafe {
objc::send(
objc::class(c"OBJC_CLASS_$_NSUserDefaults"),
objc::sel(c"standardUserDefaults"),
)
}
}
pub fn has(key: &str) -> bool {
unsafe {
let v = objc::send_id(standard(), objc::sel(c"objectForKey:"), objc::nsstring(key));
!v.is_null()
}
}
pub fn remove(key: &str) {
unsafe {
objc::send_id(
standard(),
objc::sel(c"removeObjectForKey:"),
objc::nsstring(key),
);
}
}
pub trait Persisted: Clone + Send + Sync + 'static {
fn load(key: &str, fallback: Self) -> Self;
fn store(key: &str, value: &Self);
}
impl Persisted for bool {
fn load(key: &str, fallback: Self) -> Self {
if !has(key) {
return fallback;
}
unsafe {
objc::send_id_ret_bool(standard(), objc::sel(c"boolForKey:"), objc::nsstring(key))
}
}
fn store(key: &str, value: &Self) {
unsafe {
objc::send_bool_id(
standard(),
objc::sel(c"setBool:forKey:"),
*value,
objc::nsstring(key),
);
}
}
}
impl Persisted for i64 {
fn load(key: &str, fallback: Self) -> Self {
if !has(key) {
return fallback;
}
unsafe {
objc::send_id_ret_i64(standard(), objc::sel(c"integerForKey:"), objc::nsstring(key))
}
}
fn store(key: &str, value: &Self) {
unsafe {
objc::send_i64_id(
standard(),
objc::sel(c"setInteger:forKey:"),
*value,
objc::nsstring(key),
);
}
}
}
impl Persisted for f64 {
fn load(key: &str, fallback: Self) -> Self {
if !has(key) {
return fallback;
}
unsafe {
objc::send_id_ret_f64(standard(), objc::sel(c"doubleForKey:"), objc::nsstring(key))
}
}
fn store(key: &str, value: &Self) {
unsafe {
objc::send_f64_id(
standard(),
objc::sel(c"setDouble:forKey:"),
*value,
objc::nsstring(key),
);
}
}
}
impl Persisted for String {
fn load(key: &str, fallback: Self) -> Self {
unsafe {
let s = objc::send_id(standard(), objc::sel(c"stringForKey:"), objc::nsstring(key));
if s.is_null() {
return fallback;
}
let p = objc::send_ret_ptr(s, objc::sel(c"UTF8String"));
if p.is_null() {
return fallback;
}
core::ffi::CStr::from_ptr(p as *const i8)
.to_string_lossy()
.into_owned()
}
}
fn store(key: &str, value: &Self) {
unsafe {
objc::send_id_id(
standard(),
objc::sel(c"setObject:forKey:"),
objc::nsstring(value),
objc::nsstring(key),
);
}
}
}