local_thread 0.1.1

A local thread management library for Rust. No more 'static functions in order to start threads!
Documentation
use std::{
    mem::{ManuallyDrop, MaybeUninit},
    thread::{JoinHandle, Result},
};

pub struct LocalThread<F, T> {
    res: ManuallyDrop<T>,
    func: ManuallyDrop<F>,
}

impl<F, T> LocalThread<F, T> {
    #[inline]
    pub fn new(func: F) -> Self {
        Self {
            func: ManuallyDrop::new(func),
            res: unsafe { MaybeUninit::uninit().assume_init() },
        }
    }

    pub fn spawn<'a>(&'a mut self) -> LocalJoinHandle<T>
    where
        F: FnOnce() -> T + Send + Sync + 'a,
        T: Send + Sync + 'a,
    {
        let raw_res = Raw::new(&*self.res);
        let raw_func = Raw(&self.func as *const _ as *const _);
        let handle = std::thread::spawn(move || {
            let raw_res = raw_res;
            let raw_func = raw_func;

            unsafe {
                <*mut T as From<_>>::from(raw_res)
                    .write(<*mut F as From<_>>::from(raw_func).read()())
            }
        });

        LocalJoinHandle {
            res: &mut self.res,
            handle: ManuallyDrop::new(handle),
        }
    }
}

pub struct LocalJoinHandle<'a, T> {
    res: &'a mut T,
    handle: ManuallyDrop<JoinHandle<()>>,
}

impl<'a, T> LocalJoinHandle<'a, T> {
    pub fn join(self) -> Result<T> {        
        let join_res = unsafe { core::ptr::read(&*self.handle) }.join();
        let actual_res = unsafe { core::ptr::read(&*self.res) };
        core::mem::forget(self);
        join_res.map(|_| actual_res)
    }
}

impl<'a, T> Drop for LocalJoinHandle<'a, T> {
    fn drop(&mut self) {
        unsafe { core::ptr::read(&*self.handle) }.join().unwrap()
    }
}

#[derive(Clone, Copy)]
struct Raw(*const ());

impl Raw {
    #[inline(always)]
    pub fn new<T>(val: &T) -> Self {
        Self(val as *const T as *const ())
    }
}

impl<T> From<Raw> for *const T {
    #[inline(always)]
    fn from(value: Raw) -> Self {
        value.0 as Self
    }
}

impl<T> From<Raw> for *mut T {
    #[inline(always)]
    fn from(value: Raw) -> Self {
        value.0 as Self
    }
}

unsafe impl Sync for Raw {}
unsafe impl Send for Raw {}