alua/
lib.rs

1use std::borrow::Cow;
2use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
3use std::ffi::{CStr, CString};
4use std::{rc::Rc, sync::Arc};
5
6#[cfg(feature = "arrayvec")]
7mod arrayvec;
8
9pub use alua_macros::*;
10
11pub trait TypeAnnotation {
12    fn lua_type() -> Cow<'static, str>;
13}
14
15pub trait ClassAnnotation {
16    fn class_annotation() -> String;
17}
18
19/// Assign a static string to a given type.
20macro_rules! simple {
21    ($ident:ty, $name:expr) => {
22        impl TypeAnnotation for $ident {
23            fn lua_type() -> Cow<'static, str> {
24                Cow::Borrowed($name)
25            }
26        }
27    };
28}
29
30/// Add a suffix to the wrapped type.
31macro_rules! suffix {
32    ($ident:ty, $name:expr) => {
33        impl<T: TypeAnnotation> TypeAnnotation for $ident {
34            fn lua_type() -> Cow<'static, str> {
35                T::lua_type() + $name
36            }
37        }
38    };
39}
40
41/// Ignore this type, returning the wrapped type's value instead.
42macro_rules! pass {
43    ($ident:ty) => {
44        impl<T: TypeAnnotation> TypeAnnotation for $ident{
45            fn lua_type() -> Cow<'static, str> {
46                T::lua_type()
47            }
48        }
49    };
50    ($($ident:ty),*) => {
51        $(pass!($ident);)*
52    }
53}
54
55/// Shortcut for types which convert to lua's integer.
56macro_rules! integer {
57    ($ident:ty) => {
58        simple!($ident, "integer");
59    };
60    ($($ident:ty),*) => {
61        $(integer!($ident);)*
62    }
63}
64
65/// Shortcut for types which convert to lua's string.
66macro_rules! string {
67    ($ident:ty) => {
68        simple!($ident, "string");
69    };
70    ($($ident:ty),*) => {
71        $(string!($ident);)*
72    }
73}
74
75// All types that mlua implements `IntoLua` for should also get `TypeAnnotation` implementations.
76
77// `u64`, `u128`, and `i128` are left out because I don't know how luals represents them (if at all).
78integer!(u8, u16, u32, i8, i16, i32, i64);
79
80// mlua implements `IntoLua` for `BString`, too.
81// Providing an implementation for `str` allows for `Box<str>`.
82string!(String, &str, str, CString, &CStr);
83
84simple!(f32, "number");
85simple!(f64, "number");
86simple!(bool, "boolean");
87
88pass!(Box<T>, Rc<T>, Arc<T>);
89
90suffix!(Option<T>, "?");
91suffix!(Vec<T>, "[]");
92suffix!([T], "[]");
93suffix!(&[T], "[]");
94
95impl<K: TypeAnnotation, V: TypeAnnotation> TypeAnnotation for HashMap<K, V> {
96    fn lua_type() -> Cow<'static, str> {
97        format!("table<{}, {}>", K::lua_type(), V::lua_type()).into()
98    }
99}
100
101impl<K: TypeAnnotation, V: TypeAnnotation> TypeAnnotation for BTreeMap<K, V> {
102    fn lua_type() -> Cow<'static, str> {
103        format!("table<{}, {}>", K::lua_type(), V::lua_type()).into()
104    }
105}
106
107impl<T: TypeAnnotation> TypeAnnotation for HashSet<T> {
108    fn lua_type() -> Cow<'static, str> {
109        format!("table<{}, bool>", T::lua_type()).into()
110    }
111}
112
113impl<T: TypeAnnotation> TypeAnnotation for BTreeSet<T> {
114    fn lua_type() -> Cow<'static, str> {
115        format!("table<{}, bool>", T::lua_type()).into()
116    }
117}
118
119impl<T: TypeAnnotation + Clone> TypeAnnotation for Cow<'_, T> {
120    fn lua_type() -> Cow<'static, str> {
121        T::lua_type()
122    }
123}
124
125impl TypeAnnotation for Cow<'_, str> {
126    fn lua_type() -> Cow<'static, str> {
127        str::lua_type()
128    }
129}
130
131impl<T: TypeAnnotation, const N: usize> TypeAnnotation for [T; N] {
132    fn lua_type() -> Cow<'static, str> {
133        T::lua_type() + "[]"
134    }
135}