use std::error::Error;
use std::marker::PhantomData;
use std::ops::{Deref, DerefMut};
use std::path::PathBuf;
use objc::runtime::Object;
use objc::{class, msg_send, sel, sel_impl};
use objc_id::ShareId;
use crate::foundation::{id, nil, NSData, NSString, NSUInteger};
mod bookmark_options;
pub use bookmark_options::{NSURLBookmarkCreationOption, NSURLBookmarkResolutionOption};
mod resource_keys;
pub use resource_keys::{NSURLFileResource, NSURLResourceKey, NSUbiquitousItemDownloadingStatus};
#[derive(Clone, Debug)]
pub struct NSURL<'a> {
pub objc: ShareId<Object>,
phantom: PhantomData<&'a ()>
}
impl<'a> NSURL<'a> {
pub fn retain(object: id) -> Self {
NSURL {
objc: unsafe { ShareId::from_ptr(object) },
phantom: PhantomData
}
}
pub fn from_retained(object: id) -> Self {
NSURL {
objc: unsafe { ShareId::from_retained_ptr(object) },
phantom: PhantomData
}
}
pub fn with_str(url: &str) -> Self {
let url = NSString::new(url);
Self {
objc: unsafe { ShareId::from_ptr(msg_send![class!(NSURL), URLWithString:&*url]) },
phantom: PhantomData
}
}
pub fn absolute_string(&self) -> String {
let abs_str = NSString::retain(unsafe { msg_send![&*self.objc, absoluteString] });
abs_str.to_string()
}
pub fn pathbuf(&self) -> PathBuf {
let path = NSString::retain(unsafe { msg_send![&*self.objc, path] });
path.to_str().into()
}
pub fn bookmark_data(
&self,
options: &[NSURLBookmarkCreationOption],
resource_value_keys: &[NSURLResourceKey],
relative_to_url: Option<NSURL>
) -> Result<NSData, Box<dyn Error>> {
let mut opts: NSUInteger = 0;
for mask in options {
let i: NSUInteger = mask.into();
opts = opts | i;
}
let resource_keys = nil;
let bookmark_data = NSData::retain(match relative_to_url {
Some(relative_url) => unsafe {
msg_send![&*self.objc, bookmarkDataWithOptions:opts
includingResourceValuesForKeys:resource_keys
relativeToURL:relative_url
error:nil
]
},
None => unsafe {
msg_send![&*self.objc, bookmarkDataWithOptions:opts
includingResourceValuesForKeys:resource_keys
relativeToURL:nil
error:nil
]
}
});
Ok(bookmark_data)
}
pub fn from_bookmark_data(
data: NSData,
options: &[NSURLBookmarkResolutionOption],
relative_to_url: Option<NSURL>,
data_is_stale: bool
) -> Result<Self, Box<dyn Error>> {
Err("LOL".into())
}
pub fn start_accessing_security_scoped_resource(&self) {
unsafe {
let _: () = msg_send![&*self.objc, startAccessingSecurityScopedResource];
}
}
pub fn stop_accessing_security_scoped_resource(&self) {
unsafe {
let _: () = msg_send![&*self.objc, stopAccessingSecurityScopedResource];
}
}
}
impl Deref for NSURL<'_> {
type Target = Object;
fn deref(&self) -> &Object {
&*self.objc
}
}