use enum_dispatch::enum_dispatch;
use nsi_sys::*;
use std::{
ffi::{CString, c_void},
marker::PhantomData,
pin::Pin,
};
use ustr::{Ustr, ustr};
#[allow(unused_imports)]
use crate::*;
#[inline(always)]
pub(crate) fn get_c_param_vec(
args: Option<&ArgSlice>,
) -> (i32, *const NSIParam, Vec<NSIParam>) {
let args = match args {
Some(args) => args
.iter()
.map(|arg| NSIParam {
name: arg.name.as_char_ptr(),
data: arg.data.as_c_ptr(),
type_: arg.data.type_() as _,
arraylength: arg.array_length as _,
count: (arg.data.len() / arg.array_length) as _,
flags: arg.flags as _,
})
.collect::<Vec<_>>(),
None => Vec::new(),
};
(args.len() as _, args.as_ptr(), args)
}
pub type ArgSlice<'a, 'b> = [Arg<'a, 'b>];
pub type ArgVec<'a, 'b> = Vec<Arg<'a, 'b>>;
#[derive(Debug, Clone)]
pub struct Arg<'a, 'b> {
pub(crate) name: Ustr,
pub(crate) data: ArgData<'a, 'b>,
pub(crate) array_length: usize,
pub(crate) flags: i32,
}
impl<'a, 'b> Arg<'a, 'b> {
#[inline]
pub fn new(name: &str, data: ArgData<'a, 'b>) -> Self {
Arg {
name: ustr(name),
data,
array_length: 1,
flags: 0,
}
}
#[inline]
pub fn array_len(mut self, length: usize) -> Self {
self.array_length = length;
self.flags |= NSIParamFlags::IsArray.bits();
self
}
#[inline]
pub fn per_face(mut self) -> Self {
self.flags |= NSIParamFlags::PerFace.bits();
self
}
#[inline]
pub fn per_vertex(mut self) -> Self {
self.flags |= NSIParamFlags::PerVertex.bits();
self
}
#[inline]
pub fn linear_interpolation(mut self) -> Self {
self.flags |= NSIParamFlags::InterpolateLinear.bits();
self
}
}
#[enum_dispatch(ArgData)]
pub(crate) trait ArgDataMethods {
fn type_(&self) -> DataType;
fn len(&self) -> usize;
fn as_c_ptr(&self) -> *const c_void;
}
#[enum_dispatch]
#[derive(Debug, Clone)]
pub enum ArgData<'a, 'b> {
F32,
F32Slice(F32Slice<'a>),
F64,
F64Slice(F64Slice<'a>),
I32,
I32Slice(I32Slice<'a>),
I64,
I64Slice(I64Slice<'a>),
String(String),
StringSlice(StringSlice),
Color(Color<'a>),
ColorSlice(ColorSlice<'a>),
Point(Point<'a>),
PointSlice(PointSlice<'a>),
Vector(Vector<'a>),
VectorSlice(VectorSlice<'a>),
Normal(Normal<'a>),
NormalSlice(NormalSlice<'a>),
MatrixF32(MatrixF32<'a>),
MatrixF32Slice(MatrixF32Slice<'a>),
MatrixF64(MatrixF64<'a>),
MatrixF64Slice(MatrixF64Slice<'a>),
Point4F32Slice(Point4F32Slice<'a>),
Reference(Reference<'b>),
ReferenceSlice(ReferenceSlice<'b>),
Callback(Callback<'b>),
}
macro_rules! nsi_data_def {
($type: ty, $name: ident, $nsi_type: expr) => {
#[derive(Debug, Clone, PartialEq)]
pub struct $name {
data: $type,
}
impl $name {
pub fn new(data: $type) -> Self {
Self { data }
}
}
impl ArgDataMethods for $name {
fn type_(&self) -> DataType {
$nsi_type
}
fn len(&self) -> usize {
1
}
fn as_c_ptr(&self) -> *const c_void {
&self.data as *const $type as _
}
}
};
}
macro_rules! nsi_data_array_def {
($type: ty, $name: ident, $nsi_type: expr) => {
#[derive(Debug, Clone, PartialEq)]
pub struct $name<'a> {
data: &'a [$type],
}
impl<'a> $name<'a> {
pub fn new(data: &'a [$type]) -> Self {
Self { data }
}
}
impl<'a> ArgDataMethods for $name<'a> {
fn type_(&self) -> DataType {
$nsi_type
}
fn len(&self) -> usize {
self.data.len() }
fn as_c_ptr(&self) -> *const c_void {
self.data.as_ptr() as _
}
}
};
}
macro_rules! nsi_tuple_data_array_def {
($type: ty, $name: ident, $nsi_type: expr, $len: expr ) => {
#[derive(Debug, Clone, PartialEq)]
pub struct $name<'a> {
data: &'a [[$type; $len]],
}
impl<'a> $name<'a> {
pub fn new(data: &'a [[$type; $len]]) -> Self {
Self { data }
}
}
impl<'a> ArgDataMethods for $name<'a> {
fn type_(&self) -> DataType {
$nsi_type
}
fn len(&self) -> usize {
self.data.len() }
fn as_c_ptr(&self) -> *const c_void {
self.data.as_ptr() as _
}
}
};
}
macro_rules! nsi_tuple_data_def {
($type: tt, $len: expr, $name: ident, $nsi_type: expr) => {
#[derive(Debug, Clone, PartialEq)]
pub struct $name<'a> {
data: &'a [$type; $len],
}
impl<'a> $name<'a> {
pub fn new(data: &'a [$type; $len]) -> Self {
Self { data }
}
}
impl<'a> ArgDataMethods for $name<'a> {
fn type_(&self) -> DataType {
$nsi_type
}
fn len(&self) -> usize {
1
}
fn as_c_ptr(&self) -> *const c_void {
self.data.as_ptr() as _
}
}
};
}
nsi_data_def!(f32, F32, DataType::F32);
nsi_data_def!(f64, F64, DataType::F64);
nsi_data_def!(i32, I32, DataType::I32);
nsi_data_def!(i64, I64, DataType::I64);
#[derive(Debug, Clone)]
pub struct Reference<'a> {
data: *const c_void,
_marker: PhantomData<&'a ()>,
}
unsafe impl Send for Reference<'static> {}
unsafe impl Sync for Reference<'static> {}
pub trait StableDeref<'a> {
fn stable_deref(&self) -> *const c_void;
}
impl<'a, T: ?Sized> StableDeref<'a> for &'a Box<T> {
fn stable_deref(&self) -> *const c_void {
self.as_ref() as *const T as *const c_void
}
}
impl<'a, T: ?Sized> StableDeref<'a> for &'a Arc<T> {
fn stable_deref(&self) -> *const c_void {
self.as_ref() as *const T as *const c_void
}
}
impl<'a, T: ?Sized> StableDeref<'a> for &'a Pin<Box<T>> {
fn stable_deref(&self) -> *const c_void {
self.as_ref().get_ref() as *const T as *const c_void
}
}
use std::sync::Arc;
impl<'a> Reference<'a> {
pub fn new<S: StableDeref<'a>>(data: S) -> Self {
let ptr = data.stable_deref();
debug_assert!(!ptr.is_null(), "Reference created with null pointer");
Self {
data: ptr,
_marker: PhantomData,
}
}
#[allow(clippy::borrowed_box)]
pub fn from_box<T: ?Sized>(data: &'a Box<T>) -> Self {
let ptr = data.as_ref() as *const T as *const c_void;
debug_assert!(!ptr.is_null(), "Reference created with null pointer");
Self {
data: ptr,
_marker: PhantomData,
}
}
pub fn from_arc<T: ?Sized>(data: &'a Arc<T>) -> Self {
let ptr = data.as_ref() as *const T as *const c_void;
debug_assert!(!ptr.is_null(), "Reference created with null pointer");
Self {
data: ptr,
_marker: PhantomData,
}
}
pub fn from_pin_box<T: ?Sized>(data: &'a Pin<Box<T>>) -> Self {
let ptr = data.as_ref().get_ref() as *const T as *const c_void;
debug_assert!(!ptr.is_null(), "Reference created with null pointer");
Self {
data: ptr,
_marker: PhantomData,
}
}
pub unsafe fn from_stable<T: ?Sized>(data: &'a T) -> Self {
let ptr = data as *const T as *const c_void;
debug_assert!(!ptr.is_null(), "Reference created with null pointer");
Self {
data: ptr,
_marker: PhantomData,
}
}
pub unsafe fn from_ptr(ptr: *const c_void) -> Self {
debug_assert!(!ptr.is_null(), "Reference created with null pointer");
Self {
data: ptr,
_marker: PhantomData,
}
}
}
impl<'a> ArgDataMethods for Reference<'a> {
fn type_(&self) -> DataType {
DataType::Reference
}
fn len(&self) -> usize {
1
}
fn as_c_ptr(&self) -> *const c_void {
self.data
}
}
pub trait CallbackPtr {
#[doc(hidden)]
#[allow(clippy::wrong_self_convention)]
fn to_ptr(self) -> *const c_void;
}
unsafe impl Send for Callback<'static> {}
unsafe impl Sync for Callback<'static> {}
#[derive(Debug, Clone)]
pub struct Callback<'a> {
data: *const c_void,
_marker: PhantomData<&'a mut ()>,
}
impl<'a> Callback<'a> {
pub fn new<T: CallbackPtr>(data: T) -> Self {
Self {
data: data.to_ptr(),
_marker: PhantomData,
}
}
}
impl<'a> ArgDataMethods for Callback<'a> {
fn type_(&self) -> DataType {
DataType::Reference
}
fn len(&self) -> usize {
1
}
fn as_c_ptr(&self) -> *const c_void {
self.data
}
}
#[derive(Debug, Clone)]
pub struct String {
#[allow(dead_code)]
data: CString,
pointer: *const c_void,
}
unsafe impl Send for String {}
unsafe impl Sync for String {}
impl String {
pub fn new<T: Into<Vec<u8>>>(data: T) -> Self {
let data = CString::new(data).unwrap();
let pointer = data.as_ptr() as _;
String { data, pointer }
}
}
impl ArgDataMethods for String {
fn type_(&self) -> DataType {
DataType::String
}
fn len(&self) -> usize {
1
}
fn as_c_ptr(&self) -> *const c_void {
&self.pointer as *const *const c_void as _
}
}
nsi_data_array_def!(f32, F32Slice, DataType::F32);
nsi_data_array_def!(f64, F64Slice, DataType::F64);
nsi_data_array_def!(i32, I32Slice, DataType::I32);
nsi_data_array_def!(i64, I64Slice, DataType::I64);
nsi_tuple_data_array_def!(f32, ColorSlice, DataType::Color, 3);
nsi_tuple_data_array_def!(f32, PointSlice, DataType::Point, 3);
nsi_tuple_data_array_def!(f32, VectorSlice, DataType::Vector, 3);
nsi_tuple_data_array_def!(f32, NormalSlice, DataType::Normal, 3);
nsi_tuple_data_array_def!(f32, MatrixF32Slice, DataType::MatrixF32, 16);
nsi_tuple_data_array_def!(f64, MatrixF64Slice, DataType::MatrixF64, 16);
#[derive(Debug, Clone, PartialEq)]
pub struct Point4F32Slice<'a> {
data: &'a [[f32; 4]],
}
impl<'a> Point4F32Slice<'a> {
pub fn new(data: &'a [[f32; 4]]) -> Self {
Self { data }
}
}
impl<'a> ArgDataMethods for Point4F32Slice<'a> {
fn type_(&self) -> DataType {
DataType::F32
}
fn len(&self) -> usize {
self.data.len() * 4
}
fn as_c_ptr(&self) -> *const c_void {
self.data.as_ptr() as _
}
}
#[derive(Debug, Clone)]
pub struct ReferenceSlice<'a> {
data: Vec<*const c_void>,
_marker: PhantomData<&'a ()>,
}
unsafe impl Send for ReferenceSlice<'static> {}
unsafe impl Sync for ReferenceSlice<'static> {}
impl<'a> ReferenceSlice<'a> {
pub fn new<T>(data: &'a [&'a T]) -> Self {
debug_assert_eq!(0, data.len() % DataType::Reference.elemensize());
Self {
data: data.iter().map(|r| r as *const _ as _).collect(),
_marker: PhantomData,
}
}
}
impl<'a> ArgDataMethods for ReferenceSlice<'a> {
fn type_(&self) -> DataType {
DataType::Reference
}
fn len(&self) -> usize {
self.data.len() / DataType::Reference.elemensize()
}
fn as_c_ptr(&self) -> *const c_void {
self.data.as_ptr() as _
}
}
#[derive(Debug, Clone)]
pub struct StringSlice {
#[allow(dead_code)]
data: Vec<CString>,
pointer: Vec<*const c_void>,
}
unsafe impl Send for StringSlice {}
unsafe impl Sync for StringSlice {}
impl StringSlice {
pub fn new<T: Into<Vec<u8>> + Copy>(data: &[T]) -> Self {
let data = data
.iter()
.map(|s| CString::new(*s).unwrap())
.collect::<Vec<_>>();
let pointer = data.iter().map(|s| s.as_ptr() as _).collect();
StringSlice { data, pointer }
}
}
impl ArgDataMethods for StringSlice {
fn type_(&self) -> DataType {
DataType::String
}
fn len(&self) -> usize {
self.pointer.len()
}
fn as_c_ptr(&self) -> *const c_void {
self.pointer.as_ptr() as _
}
}
nsi_tuple_data_def!(f32, 3, Color, DataType::Color);
nsi_tuple_data_def!(f32, 3, Point, DataType::Point);
nsi_tuple_data_def!(f32, 3, Vector, DataType::Vector);
nsi_tuple_data_def!(f32, 3, Normal, DataType::Normal);
nsi_tuple_data_def!(f32, 16, MatrixF32, DataType::MatrixF32);
nsi_tuple_data_def!(f64, 16, MatrixF64, DataType::MatrixF64);
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[repr(i32)]
pub(crate) enum DataType {
F32 = NSIType::F32 as _,
F64 = NSIType::F64 as _,
I32 = NSIType::I32 as _,
I64 = NSIType::I64 as _,
String = NSIType::String as _,
Color = NSIType::Color as _,
Point = NSIType::Point as _,
Vector = NSIType::Vector as _,
Normal = NSIType::Normal as _,
MatrixF32 = NSIType::MatrixF32 as _,
MatrixF64 = NSIType::MatrixF64 as _,
Reference = NSIType::Pointer as _,
}
impl DataType {
#[inline]
pub(crate) fn elemensize(&self) -> usize {
match self {
DataType::F32 => 1,
DataType::F64 => 1,
DataType::I32 => 1,
DataType::I64 => 1,
DataType::String => 1,
DataType::Color => 3,
DataType::Point => 3,
DataType::Vector => 3,
DataType::Normal => 3,
DataType::MatrixF32 => 16,
DataType::MatrixF64 => 16,
DataType::Reference => 1,
}
}
}
#[macro_export]
macro_rules! f32 {
($name: literal, $value: expr) => {
nsi::Arg::new($name, nsi::ArgData::from(nsi::F32::new($value)))
};
($name: path, $value: expr) => {{
const __ATTR_CHECK: $crate::Attribute<f32> = $name;
nsi::Arg::new(
__ATTR_CHECK.name(),
nsi::ArgData::from(nsi::F32::new($value)),
)
}};
}
#[macro_export]
macro_rules! f32_slice {
($name: literal, $value: expr) => {
nsi::Arg::new($name, nsi::ArgData::from(nsi::F32Slice::new($value)))
};
($name: path, $value: expr) => {{
const __ATTR_CHECK: $crate::Attribute<[f32]> = $name;
nsi::Arg::new(
__ATTR_CHECK.name(),
nsi::ArgData::from(nsi::F32Slice::new($value)),
)
}};
}
#[macro_export]
macro_rules! f64 {
($name: literal, $value: expr) => {
nsi::Arg::new($name, nsi::ArgData::from(nsi::F64::new($value)))
};
($name: path, $value: expr) => {{
const __ATTR_CHECK: $crate::Attribute<f64> = $name;
nsi::Arg::new(
__ATTR_CHECK.name(),
nsi::ArgData::from(nsi::F64::new($value)),
)
}};
}
#[macro_export]
macro_rules! f64_slice {
($name: literal, $value: expr) => {
nsi::Arg::new($name, nsi::ArgData::from(nsi::F64Slice::new($value)))
};
($name: path, $value: expr) => {{
const __ATTR_CHECK: $crate::Attribute<[f64]> = $name;
nsi::Arg::new(
__ATTR_CHECK.name(),
nsi::ArgData::from(nsi::F64Slice::new($value)),
)
}};
}
#[macro_export]
macro_rules! i32 {
($name: literal, $value: expr) => {
nsi::Arg::new($name, nsi::ArgData::from(nsi::I32::new($value)))
};
($name: path, $value: expr) => {{
const __ATTR_CHECK: $crate::Attribute<i32> = $name;
nsi::Arg::new(
__ATTR_CHECK.name(),
nsi::ArgData::from(nsi::I32::new($value)),
)
}};
}
#[macro_export]
macro_rules! i32_slice {
($name: literal, $value: expr) => {
nsi::Arg::new($name, nsi::ArgData::from(nsi::I32Slice::new($value)))
};
($name: path, $value: expr) => {{
const __ATTR_CHECK: $crate::Attribute<[i32]> = $name;
nsi::Arg::new(
__ATTR_CHECK.name(),
nsi::ArgData::from(nsi::I32Slice::new($value)),
)
}};
}
#[macro_export]
macro_rules! i64 {
($name: literal, $value: expr) => {
nsi::Arg::new($name, nsi::ArgData::from(nsi::I64::new($value)))
};
($name: path, $value: expr) => {{
const __ATTR_CHECK: $crate::Attribute<i64> = $name;
nsi::Arg::new(
__ATTR_CHECK.name(),
nsi::ArgData::from(nsi::I64::new($value)),
)
}};
}
#[macro_export]
macro_rules! i64_slice {
($name: literal, $value: expr) => {
nsi::Arg::new($name, nsi::ArgData::from(nsi::I64Slice::new($value)))
};
($name: path, $value: expr) => {{
const __ATTR_CHECK: $crate::Attribute<[i64]> = $name;
nsi::Arg::new(
__ATTR_CHECK.name(),
nsi::ArgData::from(nsi::I64Slice::new($value)),
)
}};
}
#[macro_export]
macro_rules! color {
($name: literal, $value: expr) => {
nsi::Arg::new($name, nsi::ArgData::from(nsi::Color::new($value)))
};
($name: path, $value: expr) => {{
const __ATTR_CHECK: $crate::Attribute<$crate::Color3F32> = $name;
nsi::Arg::new(
__ATTR_CHECK.name(),
nsi::ArgData::from(nsi::Color::new($value)),
)
}};
}
#[macro_export]
macro_rules! color_slice {
($name: literal, $value: expr) => {
nsi::Arg::new($name, nsi::ArgData::from(nsi::ColorSlice::new($value)))
};
($name: path, $value: expr) => {{
const __ATTR_CHECK: $crate::Attribute<[$crate::Color3F32]> = $name;
nsi::Arg::new(
__ATTR_CHECK.name(),
nsi::ArgData::from(nsi::ColorSlice::new($value)),
)
}};
}
#[macro_export]
macro_rules! point {
($name: literal, $value: expr) => {
nsi::Arg::new($name, nsi::ArgData::from(nsi::Point::new($value)))
};
($name: path, $value: expr) => {{
const __ATTR_CHECK: $crate::Attribute<$crate::Point3F32> = $name;
nsi::Arg::new(
__ATTR_CHECK.name(),
nsi::ArgData::from(nsi::Point::new($value)),
)
}};
}
#[macro_export]
macro_rules! point_slice {
($name: literal, $value: expr) => {
nsi::Arg::new($name, nsi::ArgData::from(nsi::PointSlice::new($value)))
};
($name: path, $value: expr) => {{
const __ATTR_CHECK: $crate::Attribute<[$crate::Point3F32]> = $name;
nsi::Arg::new(
__ATTR_CHECK.name(),
nsi::ArgData::from(nsi::PointSlice::new($value)),
)
}};
}
#[macro_export]
macro_rules! point4_f32_slice {
($name: literal, $value: expr) => {
nsi::Arg::new(
$name,
nsi::ArgData::from(nsi::Point4F32Slice::new($value)),
)
};
($name: path, $value: expr) => {{
const __ATTR_CHECK: $crate::Attribute<[$crate::Point4F32]> = $name;
nsi::Arg::new(
__ATTR_CHECK.name(),
nsi::ArgData::from(nsi::Point4F32Slice::new($value)),
)
}};
}
#[macro_export]
macro_rules! vector {
($name: literal, $value: expr) => {
nsi::Arg::new($name, nsi::ArgData::from(nsi::Vector::new($value)))
};
($name: path, $value: expr) => {{
const __ATTR_CHECK: $crate::Attribute<$crate::Vector3F32> = $name;
nsi::Arg::new(
__ATTR_CHECK.name(),
nsi::ArgData::from(nsi::Vector::new($value)),
)
}};
}
#[macro_export]
macro_rules! vector_slice {
($name: literal, $value: expr) => {
nsi::Arg::new($name, nsi::ArgData::from(nsi::VectorSlice::new($value)))
};
($name: path, $value: expr) => {{
const __ATTR_CHECK: $crate::Attribute<[$crate::Vector3F32]> = $name;
nsi::Arg::new(
__ATTR_CHECK.name(),
nsi::ArgData::from(nsi::VectorSlice::new($value)),
)
}};
}
#[macro_export]
macro_rules! normal {
($name: literal, $value: expr) => {
nsi::Arg::new($name, nsi::ArgData::from(nsi::Normal::new($value)))
};
($name: path, $value: expr) => {{
const __ATTR_CHECK: $crate::Attribute<$crate::Normal3F32> = $name;
nsi::Arg::new(
__ATTR_CHECK.name(),
nsi::ArgData::from(nsi::Normal::new($value)),
)
}};
}
#[macro_export]
macro_rules! normal_slice {
($name: literal, $value: expr) => {
nsi::Arg::new($name, nsi::ArgData::from(nsi::NormalSlice::new($value)))
};
($name: path, $value: expr) => {{
const __ATTR_CHECK: $crate::Attribute<[$crate::Normal3F32]> = $name;
nsi::Arg::new(
__ATTR_CHECK.name(),
nsi::ArgData::from(nsi::NormalSlice::new($value)),
)
}};
}
#[macro_export]
macro_rules! matrix_f32 {
($name: literal, $value: expr) => {
nsi::Arg::new($name, nsi::ArgData::from(nsi::MatrixF32::new($value)))
};
($name: path, $value: expr) => {{
const __ATTR_CHECK: $crate::Attribute<$crate::Matrix4F32> = $name;
nsi::Arg::new(
__ATTR_CHECK.name(),
nsi::ArgData::from(nsi::MatrixF32::new($value)),
)
}};
}
#[macro_export]
macro_rules! matrix_f32_slice {
($name: literal, $value: expr) => {
nsi::Arg::new(
$name,
nsi::ArgData::from(nsi::MatrixF32Slice::new($value)),
)
};
($name: path, $value: expr) => {{
const __ATTR_CHECK: $crate::Attribute<[$crate::Matrix4F32]> = $name;
nsi::Arg::new(
__ATTR_CHECK.name(),
nsi::ArgData::from(nsi::MatrixF32Slice::new($value)),
)
}};
}
#[macro_export]
macro_rules! matrix_f64 {
($name: literal, $value: expr) => {
nsi::Arg::new($name, nsi::ArgData::from(nsi::MatrixF64::new($value)))
};
($name: path, $value: expr) => {{
const __ATTR_CHECK: $crate::Attribute<$crate::Matrix4F64> = $name;
nsi::Arg::new(
__ATTR_CHECK.name(),
nsi::ArgData::from(nsi::MatrixF64::new($value)),
)
}};
}
#[macro_export]
macro_rules! matrix_f64_slice {
($name: literal, $value: expr) => {
nsi::Arg::new(
$name,
nsi::ArgData::from(nsi::MatrixF64Slice::new($value)),
)
};
($name: path, $value: expr) => {{
const __ATTR_CHECK: $crate::Attribute<[$crate::Matrix4F64]> = $name;
nsi::Arg::new(
__ATTR_CHECK.name(),
nsi::ArgData::from(nsi::MatrixF64Slice::new($value)),
)
}};
}
#[macro_export]
macro_rules! string {
($name: literal, $value: expr) => {
nsi::Arg::new($name, nsi::ArgData::from(nsi::String::new($value)))
};
($name: path, $value: expr) => {{
const __ATTR_CHECK: $crate::Attribute<&'static str> = $name;
nsi::Arg::new(
__ATTR_CHECK.name(),
nsi::ArgData::from(nsi::String::new($value)),
)
}};
}
#[macro_export]
macro_rules! string_slice {
($name: literal, $value: expr) => {
nsi::Arg::new($name, nsi::ArgData::from(nsi::StringSlice::new($value)))
};
($name: path, $value: expr) => {{
const __ATTR_CHECK: $crate::Attribute<[&'static str]> = $name;
nsi::Arg::new(
__ATTR_CHECK.name(),
nsi::ArgData::from(nsi::StringSlice::new($value)),
)
}};
}
#[macro_export]
macro_rules! reference {
($name: tt, $value: expr) => {
nsi::Arg::new($name, nsi::ArgData::from(nsi::Reference::new($value)))
};
}
#[macro_export]
macro_rules! reference_stable {
($name: tt, $value: expr) => {
nsi::Arg::new(
$name,
nsi::ArgData::from(unsafe { nsi::Reference::from_stable($value) }),
)
};
}
#[macro_export]
macro_rules! reference_slice {
($name: tt, $value: expr) => {
nsi::Arg::new(
$name,
nsi::ArgData::from(nsi::ReferenceSlice::new($value)),
)
};
}
#[macro_export]
macro_rules! callback {
($name: tt, $value: expr) => {
nsi::Arg::new($name, nsi::ArgData::from(nsi::Callback::new($value)))
};
}