use std::{ffi::c_char, ptr};
use ffi::{ClepsydreCalendar, ClepsydreCalendarClass, ClepsydreEvent, ClepsydreTimeframe};
use gdk::{RGBA, ffi::GdkRGBA};
use gio::ffi::{
GAsyncReadyCallback, GAsyncResult, GCancellable, g_task_new, g_task_propagate_boolean,
g_task_propagate_pointer, g_task_return_boolean, g_task_return_error, g_task_return_pointer,
};
use glib::{
ffi::{GError, GFALSE, GTRUE, gboolean, gpointer},
gobject_ffi::{GObject, g_object_unref},
prelude::*,
subclass::prelude::*,
translate::*,
};
use crate::{Calendar, Event, PinnedFutureResult, Timeframe};
pub trait CalendarImpl: ObjectImpl + ObjectSubclass<Type: IsA<Calendar>> {
fn try_set_name(&self, name: &str) -> Result<(), glib::Error> {
self.parent_try_set_name(name)
}
fn try_set_name_future(&self, name: &str) -> PinnedFutureResult<()> {
self.parent_try_set_name_future(name)
}
fn try_set_color(&self, color: gdk::RGBA) -> Result<(), glib::Error> {
self.parent_try_set_color(color)
}
fn try_set_color_future(&self, color: gdk::RGBA) -> PinnedFutureResult<()> {
self.parent_try_set_color_future(color)
}
fn try_set_visible(&self, visible: bool) -> Result<(), glib::Error> {
self.parent_try_set_visible(visible)
}
fn try_set_visible_future(&self, visible: bool) -> PinnedFutureResult<()> {
self.parent_try_set_visible_future(visible)
}
fn try_remove(&self) -> Result<(), glib::Error> {
self.parent_try_remove()
}
fn try_remove_future(&self) -> PinnedFutureResult<()> {
self.parent_try_remove_future()
}
fn try_create_event(
&self,
name: &str,
description: &str,
location: &str,
conference: &str,
timeframe: &Timeframe,
) -> Result<Event, glib::Error> {
self.parent_try_create_event(name, description, location, conference, timeframe)
}
fn try_create_event_future(
&self,
name: &str,
description: &str,
location: &str,
conference: &str,
timeframe: &Timeframe,
) -> PinnedFutureResult<Event> {
self.parent_try_create_event_future(name, description, location, conference, timeframe)
}
}
pub trait CalendarImplExt: CalendarImpl {
fn parent_try_set_name(&self, name: &str) -> Result<(), glib::Error> {
unsafe {
let data = Self::type_data();
let parent_class = data.as_ref().parent_class() as *mut ClepsydreCalendarClass;
let mut error = ptr::null_mut();
if let Some(f) = (*parent_class).try_set_name {
if f(
self.obj().unsafe_cast_ref::<Calendar>().to_glib_none().0,
name.to_glib_none().0,
&mut error,
) == GTRUE
{
Ok(())
} else {
Err(from_glib_full(error))
}
} else {
Err({
glib::Error::new(
crate::Error::NotImplemented,
"The method Calendar::try_set_name is not implemented",
)
})
}
}
}
fn parent_try_set_name_future(&self, _name: &str) -> PinnedFutureResult<()> {
unimplemented!()
}
fn parent_try_set_color(&self, color: gdk::RGBA) -> Result<(), glib::Error> {
unsafe {
let data = Self::type_data();
let parent_class = data.as_ref().parent_class() as *mut ClepsydreCalendarClass;
let mut error = ptr::null_mut();
if let Some(f) = (*parent_class).try_set_color {
if f(
self.obj().unsafe_cast_ref::<Calendar>().to_glib_none().0,
color.to_glib_none().0,
&mut error,
) == GTRUE
{
Ok(())
} else {
Err(from_glib_full(error))
}
} else {
Err({
glib::Error::new(
crate::Error::NotImplemented,
"The method Calendar::try_set_color is not implemented",
)
})
}
}
}
fn parent_try_set_color_future(&self, _color: gdk::RGBA) -> PinnedFutureResult<()> {
unimplemented!()
}
fn parent_try_set_visible(&self, visible: bool) -> Result<(), glib::Error> {
unsafe {
let data = Self::type_data();
let parent_class = data.as_ref().parent_class() as *mut ClepsydreCalendarClass;
let mut error = ptr::null_mut();
if let Some(f) = (*parent_class).try_set_visible {
if f(
self.obj().unsafe_cast_ref::<Calendar>().to_glib_none().0,
visible.into_glib(),
&mut error,
) == GTRUE
{
Ok(())
} else {
Err(from_glib_full(error))
}
} else {
Err({
glib::Error::new(
crate::Error::NotImplemented,
"The method Calendar::try_set_visible is not implemented",
)
})
}
}
}
fn parent_try_set_visible_future(&self, _visible: bool) -> PinnedFutureResult<()> {
unimplemented!()
}
fn parent_try_remove(&self) -> Result<(), glib::Error> {
unsafe {
let data = Self::type_data();
let parent_class = data.as_ref().parent_class() as *mut ClepsydreCalendarClass;
let mut error = ptr::null_mut();
if let Some(f) = (*parent_class).try_remove {
if f(
self.obj().unsafe_cast_ref::<Calendar>().to_glib_none().0,
&mut error,
) == GTRUE
{
Ok(())
} else {
Err(from_glib_full(error))
}
} else {
Err({
glib::Error::new(
crate::Error::NotImplemented,
"The method Calendar::try_remove is not implemented",
)
})
}
}
}
fn parent_try_remove_future(&self) -> PinnedFutureResult<()> {
unimplemented!()
}
fn parent_try_create_event(
&self,
name: &str,
description: &str,
location: &str,
conference: &str,
timeframe: &Timeframe,
) -> Result<Event, glib::Error> {
unsafe {
let data = Self::type_data();
let parent_class = data.as_ref().parent_class() as *mut ClepsydreCalendarClass;
let mut error = ptr::null_mut();
if let Some(f) = (*parent_class).try_create_event {
let event = f(
self.obj().unsafe_cast_ref::<Calendar>().to_glib_none().0,
name.to_glib_none().0,
description.to_glib_none().0,
location.to_glib_none().0,
conference.to_glib_none().0,
timeframe.to_glib_none().0,
&mut error,
);
if error.is_null() {
Ok(from_glib_full(event))
} else {
Err(from_glib_full(error))
}
} else {
Err({
glib::Error::new(
crate::Error::NotImplemented,
"The method Calendar::try_create_event is not implemented",
)
})
}
}
}
fn parent_try_create_event_future(
&self,
_name: &str,
_description: &str,
_location: &str,
_conference: &str,
_timeframe: &Timeframe,
) -> PinnedFutureResult<Event> {
unimplemented!()
}
}
impl<T: CalendarImpl> CalendarImplExt for T {}
unsafe impl<T: CalendarImpl> IsSubclassable<T> for Calendar {
fn class_init(class: &mut ::glib::Class<Self>) {
Self::parent_class_init::<T>(class);
let klass = class.as_mut();
klass.try_set_name = Some(calendar_try_set_name::<T>);
klass.try_set_name_async = Some(calendar_try_set_name_async::<T>);
klass.try_set_name_finish = Some(calendar_try_set_name_finish);
klass.try_set_color = Some(calendar_try_set_color::<T>);
klass.try_set_color_async = Some(calendar_try_set_color_async::<T>);
klass.try_set_color_finish = Some(calendar_try_set_color_finish);
klass.try_set_visible = Some(calendar_try_set_visible::<T>);
klass.try_set_visible_async = Some(calendar_try_set_visible_async::<T>);
klass.try_set_visible_finish = Some(calendar_try_set_visible_finish);
klass.try_remove = Some(calendar_try_remove::<T>);
klass.try_remove_async = Some(calendar_try_remove_async::<T>);
klass.try_remove_finish = Some(calendar_try_remove_finish);
klass.try_create_event = Some(calendar_try_create_event::<T>);
klass.try_create_event_async = Some(calendar_try_create_event_async::<T>);
klass.try_create_event_finish = Some(calendar_try_create_event_finish);
}
}
unsafe extern "C" fn calendar_try_set_name<T: CalendarImpl>(
calendar_ptr: *mut ClepsydreCalendar,
name_ptr: *const c_char,
error_ptr: *mut *mut GError,
) -> gboolean {
unsafe {
let instance = &*(calendar_ptr as *mut T::Instance);
let imp = instance.imp();
let name = glib::GStr::from_ptr(name_ptr).as_str();
match imp.try_set_name(name) {
Ok(()) => GTRUE,
Err(error) => {
if !error_ptr.is_null() {
*error_ptr = error.to_glib_full();
}
GFALSE
}
}
}
}
unsafe extern "C" fn calendar_try_set_name_async<T: CalendarImpl>(
calendar_ptr: *mut ClepsydreCalendar,
name_ptr: *const c_char,
cancellable: *mut GCancellable,
callback: GAsyncReadyCallback,
user_data: gpointer,
) {
unsafe {
let task = g_task_new(calendar_ptr as *mut _, cancellable, callback, user_data);
let instance = &*(calendar_ptr as *mut T::Instance);
let imp = instance.imp();
let name = glib::GStr::from_ptr(name_ptr).to_string().leak();
let future = imp.try_set_name_future(name);
glib::MainContext::ref_thread_default().spawn_local(async move {
match future.await {
Ok(()) => {
g_task_return_boolean(task, GTRUE);
}
Err(error) => g_task_return_error(task, error.into_glib_ptr()),
}
g_object_unref(task as *mut _);
});
}
}
unsafe extern "C" fn calendar_try_set_name_finish(
_calendar_ptr: *mut ClepsydreCalendar,
async_result: *mut GAsyncResult,
error_ptr: *mut *mut GError,
) -> gboolean {
unsafe { g_task_propagate_boolean(async_result as *mut _, error_ptr) }
}
unsafe extern "C" fn calendar_try_set_color<T: CalendarImpl>(
calendar_ptr: *mut ClepsydreCalendar,
color_ptr: *const GdkRGBA,
error_ptr: *mut *mut GError,
) -> gboolean {
unsafe {
let instance = &*(calendar_ptr as *mut T::Instance);
let imp = instance.imp();
let color = RGBA::from_glib_borrow(color_ptr);
match imp.try_set_color(*color) {
Ok(()) => GTRUE,
Err(error) => {
if !error_ptr.is_null() {
*error_ptr = error.to_glib_full();
}
GFALSE
}
}
}
}
unsafe extern "C" fn calendar_try_set_color_async<T: CalendarImpl>(
calendar_ptr: *mut ClepsydreCalendar,
color_ptr: *const GdkRGBA,
cancellable: *mut GCancellable,
callback: GAsyncReadyCallback,
user_data: gpointer,
) {
unsafe {
let task = g_task_new(calendar_ptr as *mut _, cancellable, callback, user_data);
let instance = &*(calendar_ptr as *mut T::Instance);
let imp = instance.imp();
let color = RGBA::from_glib_borrow(color_ptr);
let future = imp.try_set_color_future(*color);
glib::MainContext::ref_thread_default().spawn_local(async move {
match future.await {
Ok(()) => {
g_task_return_boolean(task, GTRUE);
}
Err(error) => g_task_return_error(task, error.into_glib_ptr()),
}
g_object_unref(task as *mut _);
});
}
}
unsafe extern "C" fn calendar_try_set_color_finish(
_calendar_ptr: *mut ClepsydreCalendar,
async_result: *mut GAsyncResult,
error_ptr: *mut *mut GError,
) -> gboolean {
unsafe { g_task_propagate_boolean(async_result as *mut _, error_ptr) }
}
unsafe extern "C" fn calendar_try_set_visible<T: CalendarImpl>(
calendar_ptr: *mut ClepsydreCalendar,
visible: gboolean,
error_ptr: *mut *mut GError,
) -> gboolean {
unsafe {
let instance = &*(calendar_ptr as *mut T::Instance);
let imp = instance.imp();
let visible = bool::from_glib(visible);
match imp.try_set_visible(visible) {
Ok(()) => GTRUE,
Err(error) => {
if !error_ptr.is_null() {
*error_ptr = error.to_glib_full();
}
GFALSE
}
}
}
}
unsafe extern "C" fn calendar_try_set_visible_async<T: CalendarImpl>(
calendar_ptr: *mut ClepsydreCalendar,
visible: gboolean,
cancellable: *mut GCancellable,
callback: GAsyncReadyCallback,
user_data: gpointer,
) {
unsafe {
let task = g_task_new(calendar_ptr as *mut _, cancellable, callback, user_data);
let instance = &*(calendar_ptr as *mut T::Instance);
let imp = instance.imp();
let future = imp.try_set_visible_future(visible == GTRUE);
glib::MainContext::ref_thread_default().spawn_local(async move {
match future.await {
Ok(()) => {
g_task_return_boolean(task, GTRUE);
}
Err(error) => g_task_return_error(task, error.into_glib_ptr()),
}
g_object_unref(task as *mut _);
});
}
}
unsafe extern "C" fn calendar_try_set_visible_finish(
_calendar_ptr: *mut ClepsydreCalendar,
async_result: *mut GAsyncResult,
error_ptr: *mut *mut GError,
) -> gboolean {
unsafe { g_task_propagate_boolean(async_result as *mut _, error_ptr) }
}
unsafe extern "C" fn calendar_try_remove<T: CalendarImpl>(
calendar_ptr: *mut ClepsydreCalendar,
error_ptr: *mut *mut GError,
) -> gboolean {
unsafe {
let instance = &*(calendar_ptr as *mut T::Instance);
let imp = instance.imp();
match imp.try_remove() {
Ok(()) => GTRUE,
Err(error) => {
if !error_ptr.is_null() {
*error_ptr = error.to_glib_full();
}
GFALSE
}
}
}
}
unsafe extern "C" fn calendar_try_remove_async<T: CalendarImpl>(
calendar_ptr: *mut ClepsydreCalendar,
cancellable: *mut GCancellable,
callback: GAsyncReadyCallback,
user_data: gpointer,
) {
unsafe {
let task = g_task_new(calendar_ptr as *mut _, cancellable, callback, user_data);
let instance = &*(calendar_ptr as *mut T::Instance);
let imp = instance.imp();
let future = imp.try_remove_future();
glib::MainContext::ref_thread_default().spawn_local(async move {
match future.await {
Ok(()) => {
g_task_return_boolean(task, GTRUE);
}
Err(error) => g_task_return_error(task, error.into_glib_ptr()),
}
g_object_unref(task as *mut _);
});
}
}
unsafe extern "C" fn calendar_try_remove_finish(
_calendar_ptr: *mut ClepsydreCalendar,
async_result: *mut GAsyncResult,
error_ptr: *mut *mut GError,
) -> gboolean {
unsafe { g_task_propagate_boolean(async_result as *mut _, error_ptr) }
}
unsafe extern "C" fn calendar_try_create_event<T: CalendarImpl>(
calendar_ptr: *mut ClepsydreCalendar,
name_ptr: *const c_char,
description_ptr: *const c_char,
location_ptr: *const c_char,
conference_ptr: *const c_char,
timeframe_ptr: *mut ClepsydreTimeframe,
error_ptr: *mut *mut GError,
) -> *mut ClepsydreEvent {
unsafe {
let instance = &*(calendar_ptr as *mut T::Instance);
let imp = instance.imp();
let name = glib::GStr::from_ptr(name_ptr).as_str();
let description = glib::GStr::from_ptr(description_ptr).as_str();
let location = glib::GStr::from_ptr(location_ptr).as_str();
let conference = glib::GStr::from_ptr(conference_ptr).as_str();
let timeframe = Timeframe::from_glib_borrow(timeframe_ptr);
match imp.try_create_event(name, description, location, conference, &timeframe) {
Ok(event) => event.to_glib_full(),
Err(error) => {
if !error_ptr.is_null() {
*error_ptr = error.to_glib_full();
}
ptr::null_mut()
}
}
}
}
unsafe extern "C" fn calendar_try_create_event_async<T: CalendarImpl>(
calendar_ptr: *mut ClepsydreCalendar,
name_ptr: *const c_char,
description_ptr: *const c_char,
location_ptr: *const c_char,
conference_ptr: *const c_char,
timeframe_ptr: *mut ClepsydreTimeframe,
cancellable: *mut GCancellable,
callback: GAsyncReadyCallback,
user_data: gpointer,
) {
unsafe {
let task = g_task_new(calendar_ptr as *mut _, cancellable, callback, user_data);
let instance = &*(calendar_ptr as *mut T::Instance);
let imp = instance.imp();
let name = glib::GStr::from_ptr(name_ptr).to_string().leak();
let description = glib::GStr::from_ptr(description_ptr).to_string().leak();
let location = glib::GStr::from_ptr(location_ptr).to_string().leak();
let conference = glib::GStr::from_ptr(conference_ptr).to_string().leak();
let timeframe = Timeframe::from_glib_borrow(timeframe_ptr);
let future =
imp.try_create_event_future(name, description, location, conference, &timeframe);
glib::MainContext::ref_thread_default().spawn_local(async move {
match future.await {
Ok(event) => {
let event_ptr: *mut ClepsydreEvent = event.to_glib_full();
g_task_return_pointer(
task,
event_ptr as gpointer,
Some(std::mem::transmute::<
unsafe extern "C" fn(*mut GObject),
unsafe extern "C" fn(gpointer),
>(g_object_unref)),
);
}
Err(error) => g_task_return_error(task, error.into_glib_ptr()),
}
g_object_unref(task as *mut _);
});
}
}
unsafe extern "C" fn calendar_try_create_event_finish(
_calendar_ptr: *mut ClepsydreCalendar,
async_result: *mut GAsyncResult,
error_ptr: *mut *mut GError,
) -> *mut ClepsydreEvent {
unsafe { g_task_propagate_pointer(async_result as *mut _, error_ptr) as *mut _ }
}
#[allow(clippy::missing_safety_doc)]
pub unsafe trait CalendarClassExt: ClassStruct {}
unsafe impl<T: ClassStruct> CalendarClassExt for T where T::Type: CalendarImpl {}