rnet 0.3.1

Easily call into Rust from C# or other .net langauges.
Documentation
use std::{marker::PhantomData, ptr};

#[derive(Copy, Clone, Debug)]
#[repr(transparent)]
pub struct RawPtr(pub *mut ());

impl Default for RawPtr {
    fn default() -> Self {
        Self(ptr::null_mut())
    }
}

#[derive(Copy, Clone, Debug)]
#[repr(C)]
pub struct RawSlice {
    pub ptr: *mut (),
    pub len: usize,
}

impl Default for RawSlice {
    fn default() -> Self {
        Self {
            ptr: ptr::null_mut(),
            len: 0,
        }
    }
}

#[derive(Copy, Clone)]
#[repr(C)]
#[rustversion::since(1.72)]
pub struct RawOpaqueHandle {
    pub ptr: *mut (),
    pub drop_fn: Option<unsafe extern "C" fn(ptr: *mut ())>,
    pub type_id: u128,
}

#[rustversion::before(1.72)]
pub struct RawOpaqueHandle {
    pub ptr: *mut (),
    pub drop_fn: Option<unsafe extern "C" fn(ptr: *mut ())>,
    pub type_id: u64,
}

impl Default for RawOpaqueHandle {
    fn default() -> Self {
        Self {
            ptr: ptr::null_mut(),
            drop_fn: None,
            type_id: Default::default(),
        }
    }
}

#[doc(hidden)]
#[derive(Copy, Clone)]
#[repr(C)]
pub struct TypeDesc {
    pub net_ty: fn(&mut GeneratorContext) -> Option<Box<str>>,
    pub base_ty: fn(&mut GeneratorContext) -> Option<Box<str>>,
    pub raw_ty: fn(&mut GeneratorContext) -> Option<Box<str>>,
    pub marshal_in: Option<fn(&mut GeneratorContext, &str) -> Box<str>>,
    pub marshal_out: Option<fn(&mut GeneratorContext, &str) -> Box<str>>,
}

#[doc(hidden)]
#[derive(Copy, Clone)]
#[repr(C)]
pub struct ArgDesc {
    pub name: &'static str,
    pub ty_: &'static TypeDesc,
}

#[doc(hidden)]
#[derive(Copy, Clone)]
#[repr(C)]
pub struct FnDesc {
    pub name: &'static str,
    pub args: &'static [ArgDesc],
    pub ret_ty: &'static TypeDesc,
}

#[doc(hidden)]
#[derive(Copy, Clone)]
#[repr(C)]
pub struct FieldDesc {
    pub name: &'static str,
    pub ty_: &'static TypeDesc,
}

#[doc(hidden)]
#[derive(Copy, Clone)]
#[repr(C)]
pub struct StructDesc {
    pub name: &'static str,
    pub fields: &'static [FieldDesc],
}

#[doc(hidden)]
#[derive(Default, Copy, Clone)]
#[repr(C)]
pub struct LibDesc {
    pub fns: &'static [FnDesc],
    pub structs: &'static [StructDesc],
}

#[derive(Copy, Clone)]
#[repr(C)]
pub struct RawDelegate {
    pub call_fn: *mut (),
    pub manage_fn: Option<extern "C" fn(*mut (), i32)>,
}

impl Default for RawDelegate {
    fn default() -> Self {
        Self {
            call_fn: ptr::null_mut(),
            manage_fn: None,
        }
    }
}

#[doc(hidden)]
#[repr(C)]
pub struct GeneratorContext<'a> {
    counter: u32,
    add_item_data: *mut (),
    add_item: fn(*mut (), item: &str),
    add_tuple_data: *mut (),
    add_tuple: fn(*mut (), elems: &[Box<str>]) -> Box<str>,
    phantom: PhantomData<&'a ()>,
}

impl<'a> GeneratorContext<'a> {
    #[doc(hidden)]
    pub fn new<F: FnMut(&str), G: FnMut(&[Box<str>]) -> Box<str>>(
        add_item: &'a mut F,
        add_tuple: &'a mut G,
    ) -> Self {
        fn add_item_thunk<F: FnMut(&str)>(ptr: *mut (), item: &str) {
            let f = unsafe { &mut *(ptr as *mut F) };
            f(item);
        }
        fn add_tuple_thunk<G: FnMut(&[Box<str>]) -> Box<str>>(
            ptr: *mut (),
            elems: &[Box<str>],
        ) -> Box<str> {
            let g = unsafe { &mut *(ptr as *mut G) };
            g(elems)
        }
        Self {
            counter: 0,
            add_item_data: add_item as *mut F as *mut (),
            add_item: add_item_thunk::<F>,
            add_tuple_data: add_tuple as *mut G as *mut (),
            add_tuple: add_tuple_thunk::<G>,
            phantom: PhantomData,
        }
    }
    #[doc(hidden)]
    pub fn get_unique_identifier(&mut self, prefix: &str) -> String {
        self.counter += 1;
        format!("{}{}", prefix, self.counter)
    }
    #[doc(hidden)]
    pub fn add_item(&mut self, item: &str) {
        (self.add_item)(self.add_item_data, item)
    }
    #[doc(hidden)]
    pub fn add_tuple(&mut self, elems: &[Box<str>]) -> Box<str> {
        (self.add_tuple)(self.add_tuple_data, elems)
    }
}