basic api definition interface

This commit is contained in:
pointer-to-bios 2024-09-23 12:56:35 +08:00
commit f7ae7281b3
4 changed files with 101 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/target

6
Cargo.toml Normal file
View File

@ -0,0 +1,6 @@
[package]
name = "nonx"
version = "0.1.0"
edition = "2021"
[dependencies]

10
src/lib.rs Normal file
View File

@ -0,0 +1,10 @@
#![no_std]
extern crate alloc;
pub mod utils;
api_remapper! {
api!(nonx::mem::alloc(size: usize, align: usize) -> *mut u8);
api!(nonx::mem::free(ptr: *mut u8, size: usize, align: usize));
}

84
src/utils.rs Normal file
View File

@ -0,0 +1,84 @@
use alloc::{collections::btree_map::BTreeMap, string::String, vec::Vec};
use crate::api_remapper_fn;
pub struct Call {
pub args: &'static str,
pub rets: &'static str,
}
pub(crate) static mut APIMAP: BTreeMap<
&'static str,
BTreeMap<&'static str, BTreeMap<&'static str, Call>>,
> = BTreeMap::new();
#[macro_export]
macro_rules! api {
($dev: ident :: $modu: ident :: $name: ident ($($arg:tt)*)) => {
api_map_add(stringify!($dev::$modu::$name), Call {args: stringify!($($arg)*), rets: "()"});
};
($dev: ident :: $modu: ident :: $name: ident ($($arg:tt)*) -> $ret:ty) => {
api_map_add(stringify!($dev::$modu::$name), Call {args: stringify!($($arg)*), rets: stringify!($ret)});
};
}
#[macro_export]
macro_rules! api_remapper {
($($st:stmt;)*) => {
fn api_remapper_fn() {
use crate::utils::*;
$(
$st
)*
}
};
}
static mut APIMAP_INITED: bool = false;
pub fn api_map_inited() -> bool {
unsafe { APIMAP_INITED }
}
pub fn api_remap() {
unsafe { APIMAP_INITED = true };
api_remapper_fn();
}
pub fn api_map_get(path: &[String]) -> &'static Call {
unsafe {
APIMAP
.get(path[0].as_str())
.unwrap()
.get(path[1].as_str())
.unwrap()
.get(path[2].as_str())
.unwrap()
}
}
pub(crate) fn api_map_add<'a>(path: &'static str, call: Call) {
let path = path
.split("::")
.map(|s| s.trim())
.collect::<Vec<&'static str>>();
let developer = if let Some(developer) = unsafe { APIMAP.get_mut(path[0]) } {
developer
} else {
unsafe {
APIMAP.insert(path[0], BTreeMap::new());
APIMAP.get_mut(path[0]).unwrap()
}
};
let module = if let Some(module) = developer.get_mut(path[1]) {
module
} else {
developer.insert(path[1], BTreeMap::new());
developer.get_mut(path[1]).unwrap()
};
if let Some(_) = module.get(path[2]) {
panic!("Duplicate api name {:?}.", path);
} else {
module.insert(path[2], call);
}
}