tank-sqlite 0.36.0

SQLite driver implementation for Tank: the Rust data layer
Documentation
use std::{
    ops::{Deref, DerefMut},
    sync::atomic::AtomicPtr,
};

pub(crate) trait NullCheck {
    fn is_null(&self) -> bool;
}

impl<T> NullCheck for *const T {
    fn is_null(&self) -> bool {
        (*self as *const T).is_null()
    }
}

impl<T> NullCheck for *mut T {
    fn is_null(&self) -> bool {
        (*self as *const T).is_null()
    }
}

impl<T> NullCheck for AtomicPtr<T> {
    fn is_null(&self) -> bool {
        self.load(std::sync::atomic::Ordering::Relaxed).is_null()
    }
}

impl<T: NullCheck> NullCheck for &T {
    fn is_null(&self) -> bool {
        (*self).is_null()
    }
}

impl<T: NullCheck> NullCheck for &mut T {
    fn is_null(&self) -> bool {
        false
    }
}

#[derive(Debug)]
pub(crate) struct CBox<T: NullCheck> {
    pub(crate) ptr: T,
    dealloc: fn(T),
}

impl<T: NullCheck> CBox<T> {
    pub fn new(ptr: T, dealloc: fn(T)) -> Self {
        Self { ptr, dealloc }
    }
}

impl<T: NullCheck> Drop for CBox<T> {
    fn drop(&mut self) {
        if !self.is_null() {
            unsafe {
                (self.dealloc)(std::ptr::read(&self.ptr as *const T));
            }
        }
    }
}

impl<T: NullCheck> Deref for CBox<T> {
    type Target = T;

    fn deref(&self) -> &Self::Target {
        &self.ptr
    }
}

impl<T: NullCheck> DerefMut for CBox<T> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.ptr
    }
}

unsafe impl<T: NullCheck> Send for CBox<T> {}
unsafe impl<T: NullCheck> Sync for CBox<T> {}