clepsydre-rebind 0.2.0

Safe bindings for libclepsydre
// rustdoc-stripper-ignore-next
//! Traits intended for subclassing [`Subscription`].

use ffi::ClepsydreSubscription;
use glib::{DateTime, ffi::GDateTime, prelude::*, subclass::prelude::*, translate::*};

use crate::Subscription;

pub trait SubscriptionImpl: ObjectImpl + ObjectSubclass<Type: IsA<Subscription>> {
    fn set_timeframe(&self, start: &DateTime, end: &DateTime) {
        self.parent_set_timeframe(start, end)
    }
}

pub trait SubscriptionImplExt: SubscriptionImpl {
    fn parent_set_timeframe(&self, start: &DateTime, end: &DateTime) {
        unsafe {
            let data = Self::type_data();
            let parent_class = data.as_ref().parent_class() as *mut ffi::ClepsydreSubscriptionClass;
            if let Some(f) = (*parent_class).set_timeframe {
                f(
                    self.obj()
                        .unsafe_cast_ref::<Subscription>()
                        .to_glib_none()
                        .0,
                    start.to_glib_none().0,
                    end.to_glib_none().0,
                );
            } else {
                unimplemented!()
            }
        }
    }
}

impl<T: SubscriptionImpl> SubscriptionImplExt for T {}

unsafe impl<T: SubscriptionImpl> IsSubclassable<T> for Subscription {
    fn class_init(class: &mut ::glib::Class<Self>) {
        Self::parent_class_init::<T>(class);

        let klass = class.as_mut();
        klass.set_timeframe = Some(subscription_set_timeframe::<T>);
    }
}

/// # Safety
///
/// - `manager_ptr` has to be a pointer to a valid ClepsydreManager instance.
/// - `search_ptr` has to be a valid, null-terminated UTF-8 string.
/// - `error_ptr` has to be NULL, or to point to a writable region of memory.
unsafe extern "C" fn subscription_set_timeframe<T: SubscriptionImpl>(
    subscription_ptr: *mut ClepsydreSubscription,
    start_ptr: *mut GDateTime,
    end_ptr: *mut GDateTime,
) {
    unsafe {
        let instance = &*(subscription_ptr as *mut T::Instance);
        let imp = instance.imp();
        let start = DateTime::from_glib_borrow(start_ptr);
        let end = DateTime::from_glib_borrow(end_ptr);

        imp.set_timeframe(&start, &end)
    }
}

#[allow(clippy::missing_safety_doc)]
pub unsafe trait SubscriptionClassExt: ClassStruct {}

unsafe impl<T: ClassStruct> SubscriptionClassExt for T where T::Type: SubscriptionImpl {}