Fixed rust, named the libraries sdk's, better examples

This commit is contained in:
2024-06-16 00:59:04 +03:00
parent 407faab33a
commit f55279b7ef
20 changed files with 229 additions and 226 deletions

13
sdk/rust/Cargo.toml Normal file
View File

@@ -0,0 +1,13 @@
[package]
name = "dim_sdk"
version = "0.1.0"
edition = "2021"
[lib]
name="dim_sdk"
[dependencies]
anyhow = "1.0.86"
bytes = "1.6.0"
lazy_static = { version = "1.4.0", features = ["spin"] }
libc = "0.2.155"

36
sdk/rust/src/c_buffer.rs Normal file
View File

@@ -0,0 +1,36 @@
#[derive(Debug)]
pub struct CBuffer<'a> {
inner: &'a mut [i8],
count: usize,
capacity: usize
}
#[allow(dead_code)] // rust_analyzer too dumb to see my macro magic
// i hate that macro as much as you do
impl CBuffer<'_> {
pub fn from_raw_parts_mut(buf: *mut i8, capacity: usize) -> Self {
Self {
inner: unsafe {
std::slice::from_raw_parts_mut(buf, capacity)
},
capacity,
count: 0,
}
}
}
impl std::fmt::Write for CBuffer<'_> {
fn write_str(&mut self, buf: &str) -> Result<(), std::fmt::Error> {
for c in buf.as_bytes() {
if self.count >= self.capacity - 1 {
return Ok(());
}
self.inner[self.count] = *c as i8;
self.count += 1;
}
self.inner[self.count] = 0;
Ok(())
}
}

25
sdk/rust/src/lib.rs Normal file
View File

@@ -0,0 +1,25 @@
#[macro_use]
mod magic;
mod c_buffer;
mod plugin_info;
pub use c_buffer::*;
pub use plugin_info::*;
pub use anyhow::Result;
pub trait DimPlugin {
fn init(&mut self);
fn pre_reload(&mut self);
fn post_reload(&mut self);
fn poll(&mut self, f: &mut CBuffer) -> Result<()>;
fn free(&mut self) {}
}

53
sdk/rust/src/magic.rs Normal file
View File

@@ -0,0 +1,53 @@
// Lord have mercy on me
#[macro_export]
macro_rules! plugin_info {
($typ:ty, $name:literal, $version:literal, $license:literal) => {
lazy_static::lazy_static!(
static ref PLUGIN_INFO: $crate::PluginInfo = $crate::PluginInfo::new($name, $version, $license);
);
static mut PLUG: *mut $typ = std::ptr::null_mut() as *mut $typ;
#[no_mangle]
unsafe extern "C" fn plug_get_info() -> *const std::ffi::c_void {
PLUGIN_INFO.get_raw_ptr()
}
#[no_mangle]
unsafe extern "C" fn plug_init() {
PLUG = std::alloc::alloc(std::alloc::Layout::new::<$typ>()) as *mut $typ;
*PLUG = Plug::new();
(&mut *PLUG).init();
}
#[no_mangle]
unsafe extern "C" fn plug_pre_reload() -> *mut $typ {
//TODO: Untested
(&mut *PLUG).pre_reload();
return PLUG;
}
#[no_mangle]
unsafe extern "C" fn plug_post_reload(state: *mut $typ) {
//TODO: Untested
PLUG = state;
(&mut *PLUG).post_reload();
}
#[no_mangle]
unsafe extern "C" fn plug_poll(buf: *mut i8, len: std::ffi::c_uint) {
let mut buf = $crate::CBuffer::from_raw_parts_mut(buf, len as usize);
if let Err(_e) = (&mut *PLUG).poll(&mut buf) {
// TODO: Handle error maybe?
}
}
#[no_mangle]
unsafe extern "C" fn plug_free() {
std::alloc::dealloc(PLUG as *mut u8, std::alloc::Layout::new::<$typ>());
(&mut *PLUG).free();
}
};
}

View File

@@ -0,0 +1,41 @@
use std::ffi::{c_char, c_void, CString};
#[derive(Debug)]
pub struct PluginInfo {
ptrs: PluginInfoPtrs,
_name: CString,
_version: CString,
_license: CString
}
#[repr(C)]
#[derive(Debug)]
struct PluginInfoPtrs {
name: *const c_char,
version: *const c_char,
license: *const c_char,
}
impl PluginInfo {
pub fn new(name: &str, version: &str, license: &str) -> Self {
let _name = CString::new(name).unwrap();
let _version = CString::new(version).unwrap();
let _license = CString::new(license).unwrap();
let name = _name.as_ptr();
let version = if _version.is_empty() {
std::ptr::null()
} else {_version.as_ptr()};
let license = if _license.is_empty() {
std::ptr::null()
} else {_license.as_ptr()};
Self { ptrs: PluginInfoPtrs{ name, version, license }, _name, _version, _license }
}
pub fn get_raw_ptr(&self) -> *const c_void {
&self.ptrs as *const _ as *const c_void
}
}
unsafe impl Sync for PluginInfo {}