browser-window-core 0.2.1

The non-user friendly inner functionality of crate browser-window, providing an cross-platform and browser engine independent interface.
Documentation
use super::*;

use std::{
	borrow::Cow,
	ffi::c_void,
	ops::Add,
	os::raw::c_uint,
	mem::MaybeUninit,
	ptr,
	time::{Duration, SystemTime}
};

use browser_window_c::*;



pub struct CookieImpl {
	pub(in crate) inner: *mut cbw_Cookie
}

pub struct CookieMutImpl (CookieImpl);

pub struct CookieJarImpl {
	pub(in crate) inner: *mut cbw_CookieJar
}

pub struct CookieIteratorImpl {
	pub(in crate) inner: *mut cbw_CookieIterator
}

struct CookieStorageCallbackData {
	callback: CookieStorageCallbackFn,
	data: *mut ()
}

struct CookieDeleteCallbackData {
	callback: CookieDeleteCallbackFn,
	data: *mut ()
}

struct CookieIteratorNextCallbackData {
	callback: CookieIteratorNextCallbackFn,
	data: *mut ()
}



impl CookieExt for CookieImpl {

	fn creation_time(&self) -> SystemTime {
		let timestamp = unsafe { cbw_Cookie_getCreationTime(self.inner) };

		SystemTime::UNIX_EPOCH.add(Duration::from_millis(timestamp))
	}

	fn expires(&self) -> Option<SystemTime> {
		let timestamp = unsafe { cbw_Cookie_getExpires(self.inner) };

		if timestamp != 0 {
			Some( SystemTime::UNIX_EPOCH.add(Duration::from_millis(timestamp)) )
		}
		else {
			None
		}
	}

	fn domain<'a>(&'a self) -> Cow<'a, str> {
		let mut slice: cbw_StrSlice = unsafe { MaybeUninit::uninit().assume_init() };
		let owned = unsafe { cbw_Cookie_getDomain(self.inner, &mut slice) };

		if owned > 0 {
			let string: String = slice.into();
			unsafe { cbw_string_free(slice) };
			string.into()
		}
		else {
			let string: &str = slice.into();
			string.into()
		}
	}

	fn free(&mut self) {
		unsafe { cbw_Cookie_free(self.inner) };
	}

	fn is_http_only(&self) -> bool {
		(unsafe { cbw_Cookie_isHttpOnly(self.inner) }) > 0
	}

	fn is_secure(&self) -> bool {
		(unsafe { cbw_Cookie_isSecure(self.inner) }) > 0
	}

	fn name<'a>(&'a self) -> Cow<'a, str> {
		let mut slice: cbw_StrSlice = unsafe { MaybeUninit::uninit().assume_init() };
		let owned = unsafe { cbw_Cookie_getName(self.inner, &mut slice) };

		if owned > 0 {
			let string: String = slice.into();
			unsafe { cbw_string_free(slice) };
			string.into()
		}
		else {
			let string: &str = slice.into();
			string.into()
		}
	}

	fn new(name: &str, value: &str) -> Self {
		let inner = unsafe { cbw_Cookie_new(name.into(), value.into()) };

		Self { inner }
	}

	fn path<'a>(&'a self) -> Cow<'a, str> {
		let mut slice: cbw_StrSlice = unsafe { MaybeUninit::uninit().assume_init() };
		let owned = unsafe { cbw_Cookie_getPath(self.inner, &mut slice) };

		if owned > 0 {
			let string: String = slice.into();
			unsafe { cbw_string_free(slice) };
			string.into()
		}
		else {
			let string: &str = slice.into();
			string.into()
		}
	}

	fn value<'a>(&'a self) -> Cow<'a, str> {
		let mut slice: cbw_StrSlice = unsafe { MaybeUninit::uninit().assume_init() };

		let owned = unsafe { cbw_Cookie_getValue(self.inner, &mut slice) };
		
		if owned > 0 {
			let string: String = slice.into();
			unsafe { cbw_string_free(slice) };
			string.into()
		}
		else {
			let string: &str = slice.into();
			string.into()
		}
	}
	
	fn make_http_only(&mut self) -> &mut Self {
		unsafe { cbw_Cookie_makeHttpOnly(self.inner) };	self
	}

	fn make_secure(&mut self) -> &mut Self {
		unsafe { cbw_Cookie_makeSecure(self.inner) };	self
	}

	fn set_creation_time(&mut self, time: &SystemTime) -> &mut Self {
		unsafe { cbw_Cookie_setCreationTime(self.inner, time.duration_since(SystemTime::UNIX_EPOCH).unwrap().as_millis() as _) };	self
	}

	fn set_expires(&mut self, time: &SystemTime) -> &mut Self {
		unsafe { cbw_Cookie_setExpires(self.inner, time.duration_since(SystemTime::UNIX_EPOCH).unwrap().as_millis() as _) };	self
	}

	fn set_domain(&mut self, domain: &str) -> &mut Self {
		unsafe { cbw_Cookie_setDomain(self.inner, domain.into()) };	self
	}

	fn set_name(&mut self, name: &str) -> &mut Self {
		unsafe { cbw_Cookie_setName(self.inner, name.into()) };	self
	}


	fn set_path(&mut self, path: &str) -> &mut Self {
		unsafe { cbw_Cookie_setPath(self.inner, path.into()) };	self
	}

	fn set_value(&mut self, value: &str) -> &mut Self{
		unsafe { cbw_Cookie_setValue(self.inner, value.into()) };	self
	}
}

impl CookieJarExt for CookieJarImpl {

	fn delete(&mut self, url: &str, name: &str, complete_cb: CookieDeleteCallbackFn, cb_data: *mut ()) {
		let data = Box::into_raw(Box::new(CookieDeleteCallbackData {
			callback: complete_cb,
			data: cb_data
		}));

		unsafe { cbw_CookieJar_delete(self.inner, url.into(), name.into(), Some(ffi_cookie_delete_callback_handler), data as _ ) };
	}

	fn free(&mut self) {
		unsafe { cbw_CookieJar_free(self.inner) };
	}

	fn global() -> CookieJarImpl {
		let inner = unsafe { cbw_CookieJar_newGlobal() };

		CookieJarImpl {
			inner
		}
	}

	fn iterator<'a>(&'a self, url: &str, include_http_only: bool) -> CookieIteratorImpl {
		let mut iterator: CookieIteratorImpl = unsafe { MaybeUninit::uninit().assume_init() };
		unsafe { cbw_CookieJar_iterator(self.inner, &mut iterator.inner, if include_http_only {1} else {0}, url.into()) };
		
		return iterator;
	}

	fn iterator_all<'a>(&'a self) -> CookieIteratorImpl {
		let mut iterator: CookieIteratorImpl = unsafe { MaybeUninit::uninit().assume_init() };
		unsafe { cbw_CookieJar_iteratorAll(self.inner, &mut iterator.inner) };
		
		return iterator;
	}

	fn store(&mut self, url: &str, cookie: &CookieImpl, complete_cb: Option<CookieStorageCallbackFn>, cb_data: *mut ()) {
		let data = if !complete_cb.is_none() {
			Box::into_raw( Box::new( CookieStorageCallbackData {
				callback: complete_cb.unwrap(),
				data: cb_data
			}))
		}
		else {
			ptr::null_mut()
		};

		unsafe {
			let mut error = cbw_CookieJar_store(
				self.inner,
				url.into(),
				cookie.inner,
				complete_cb.map(|_| ffi_cookie_storage_callback_handler as _),
				data as _
			);

			if error.code != 0 && !complete_cb.is_none() {
				(complete_cb.unwrap())(CookieJarImpl {inner: self.inner}, cb_data, Err(CookieStorageError::Unknown));
			}

			cbw_Err_free(&mut error);
		}
	}
}

impl CookieIteratorExt for CookieIteratorImpl {
	fn free(&mut self) {
		unsafe { cbw_CookieIterator_free(self.inner) }
	}

	fn next(&mut self, on_next: CookieIteratorNextCallbackFn, cb_data: *mut ()) -> bool {
		let data = Box::into_raw(Box::new(CookieIteratorNextCallbackData {
			callback: on_next,
			data: cb_data
		}));

		let success = unsafe { cbw_CookieIterator_next(self.inner, Some(ffi_cookie_iterator_next_handler), data as _) };
		
		return success > 0;
	}
}




unsafe extern "C" fn ffi_cookie_storage_callback_handler(cookie_jar: *mut cbw_CookieJar, _data: *mut c_void, error: cbw_Err) {

	let data_ptr = _data as *mut CookieStorageCallbackData;
	let data: Box<CookieStorageCallbackData> = Box::from_raw( data_ptr );

	let handle = CookieJarImpl {inner: cookie_jar};
	let result = if error.code == 0 {
		Ok(())
	}
	else {
		Err(CookieStorageError::Unknown)
	};

	(data.callback)( handle, data.data, result );
}

unsafe extern "C" fn ffi_cookie_delete_callback_handler(cookie_jar: *mut cbw_CookieJar, _data: *mut c_void, deleted: c_uint) {

	let data_ptr = _data as *mut CookieDeleteCallbackData;
	let data: Box<CookieDeleteCallbackData> = Box::from_raw( data_ptr );

	let handle = CookieJarImpl {inner: cookie_jar};

	(data.callback)( handle, data.data, deleted as _ );
}

unsafe extern "C" fn ffi_cookie_iterator_next_handler(cookie_iterator: *mut cbw_CookieIterator, _data: *mut c_void, _cookie: *mut cbw_Cookie) {
	let data_ptr = _data as *mut CookieIteratorNextCallbackData;
	let data: Box<CookieIteratorNextCallbackData> = Box::from_raw(data_ptr);

	let handle = CookieIteratorImpl {inner: cookie_iterator};
	let cookie = if _cookie == ptr::null_mut() {
		None
	}
	else {
		Some(CookieImpl {inner: _cookie})
	};

	(data.callback)(handle, data.data, cookie);
}