teal: add documentation for types, fields, and functions
ci/woodpecker/push/debug Pipeline was successful
Details
ci/woodpecker/push/debug Pipeline was successful
Details
This commit is contained in:
parent
4c1a1588c5
commit
feb93f2b4e
|
@ -17,6 +17,7 @@ pub struct FunctionDesc {
|
||||||
pub args: Vec<FuncArg>,
|
pub args: Vec<FuncArg>,
|
||||||
/// The return type of the function, `None` if it returns nothing
|
/// The return type of the function, `None` if it returns nothing
|
||||||
pub return_ty: Option<Type>,
|
pub return_ty: Option<Type>,
|
||||||
|
pub docs: Option<Vec<String>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GenerateTealDefinition for FunctionDesc {
|
impl GenerateTealDefinition for FunctionDesc {
|
||||||
|
@ -58,6 +59,7 @@ pub struct FieldDesc {
|
||||||
pub ty: Type,
|
pub ty: Type,
|
||||||
/// A boolean indicating if there is a setter for this field.
|
/// A boolean indicating if there is a setter for this field.
|
||||||
pub can_set: bool,
|
pub can_set: bool,
|
||||||
|
pub docs: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GenerateTealDefinition for FieldDesc {
|
impl GenerateTealDefinition for FieldDesc {
|
||||||
|
|
|
@ -42,7 +42,10 @@ where
|
||||||
inner: MutCow<'a, UserdataBuilder<'a, T>>,
|
inner: MutCow<'a, UserdataBuilder<'a, T>>,
|
||||||
pub(crate) fields: HashMap<String, FieldDesc>,
|
pub(crate) fields: HashMap<String, FieldDesc>,
|
||||||
pub(crate) funcs: HashMap<String, FunctionDesc>,
|
pub(crate) funcs: HashMap<String, FunctionDesc>,
|
||||||
|
pub(crate) type_docs: Vec<String>, // each element is a new line
|
||||||
func_arg_names: Option<Vec<String>>,
|
func_arg_names: Option<Vec<String>>,
|
||||||
|
/// docs that will be added to a field or function that will soon be added
|
||||||
|
pub(crate) queued_docs: Option<Vec<String>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: Userdata> From<&'a mut UserdataBuilder<'a, T>> for TealUserdataBuilder<'a, T> {
|
impl<'a, T: Userdata> From<&'a mut UserdataBuilder<'a, T>> for TealUserdataBuilder<'a, T> {
|
||||||
|
@ -51,12 +54,14 @@ impl<'a, T: Userdata> From<&'a mut UserdataBuilder<'a, T>> for TealUserdataBuild
|
||||||
inner: MutCow::Borrowed(value),
|
inner: MutCow::Borrowed(value),
|
||||||
funcs: Default::default(),
|
funcs: Default::default(),
|
||||||
fields: Default::default(),
|
fields: Default::default(),
|
||||||
|
type_docs: Default::default(),
|
||||||
func_arg_names: None,
|
func_arg_names: None,
|
||||||
|
queued_docs: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn function_desc<'a, A, R>(func_arg_names: &mut Option<Vec<String>>, fn_name: &str) -> FunctionDesc
|
pub(crate) fn function_desc<'a, A, R>(func_arg_names: &mut Option<Vec<String>>, docs: &mut Option<Vec<String>>, fn_name: &str) -> FunctionDesc
|
||||||
where
|
where
|
||||||
A: FromLuaVec<'a> + LuaTypeName,
|
A: FromLuaVec<'a> + LuaTypeName,
|
||||||
R: AsLua<'a> + LuaTypeName,
|
R: AsLua<'a> + LuaTypeName,
|
||||||
|
@ -118,6 +123,8 @@ where
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let docs = docs.take();
|
||||||
|
|
||||||
let ret_name = R::get_lua_name();
|
let ret_name = R::get_lua_name();
|
||||||
let ret_ty = match ret_name.as_str() {
|
let ret_ty = match ret_name.as_str() {
|
||||||
"()" => None,
|
"()" => None,
|
||||||
|
@ -129,6 +136,7 @@ where
|
||||||
is_field: true,
|
is_field: true,
|
||||||
args,
|
args,
|
||||||
return_ty: ret_ty,
|
return_ty: ret_ty,
|
||||||
|
docs,
|
||||||
};
|
};
|
||||||
|
|
||||||
func_desc
|
func_desc
|
||||||
|
@ -140,16 +148,38 @@ impl<'a, T: Userdata> TealUserdataBuilder<'a, T> {
|
||||||
inner: MutCow::Owned(UserdataBuilder::new()),
|
inner: MutCow::Owned(UserdataBuilder::new()),
|
||||||
fields: Default::default(),
|
fields: Default::default(),
|
||||||
funcs: Default::default(),
|
funcs: Default::default(),
|
||||||
|
type_docs: Default::default(),
|
||||||
func_arg_names: None,
|
func_arg_names: None,
|
||||||
|
queued_docs: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Add documentation for this type
|
||||||
|
pub fn document_type(&mut self, text: &str) -> &mut Self {
|
||||||
|
self.type_docs.push(text.to_string());
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Add documentation for a field, or function that will added right after this
|
||||||
|
pub fn document(&mut self, text: &str) -> &mut Self {
|
||||||
|
if self.queued_docs.is_none() {
|
||||||
|
self.queued_docs = Some(Vec::default());
|
||||||
|
}
|
||||||
|
|
||||||
|
let docs = self.queued_docs.as_mut().unwrap();
|
||||||
|
docs.push(text.to_string());
|
||||||
|
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
pub fn field_getter<F, R>(&mut self, name: &str, f: F) -> &mut Self
|
pub fn field_getter<F, R>(&mut self, name: &str, f: F) -> &mut Self
|
||||||
where
|
where
|
||||||
F: Fn(&'a State, &T) -> crate::Result<R> + 'static,
|
F: Fn(&'a State, &T) -> crate::Result<R> + 'static,
|
||||||
R: AsLua<'a> + LuaTypeName,
|
R: AsLua<'a> + LuaTypeName,
|
||||||
T: TealUserdata + 'static
|
T: TealUserdata + 'static
|
||||||
{
|
{
|
||||||
|
let docs = self.queued_docs.take().unwrap_or_default();
|
||||||
|
|
||||||
let tname = R::get_lua_name();
|
let tname = R::get_lua_name();
|
||||||
// maybe field_setter was ran first
|
// maybe field_setter was ran first
|
||||||
if !self.fields.contains_key(&tname) {
|
if !self.fields.contains_key(&tname) {
|
||||||
|
@ -159,6 +189,7 @@ impl<'a, T: Userdata> TealUserdataBuilder<'a, T> {
|
||||||
name: tname.clone(),
|
name: tname.clone(),
|
||||||
},
|
},
|
||||||
can_set: false,
|
can_set: false,
|
||||||
|
docs,
|
||||||
};
|
};
|
||||||
|
|
||||||
self.fields.insert(tname, desc);
|
self.fields.insert(tname, desc);
|
||||||
|
@ -174,6 +205,8 @@ impl<'a, T: Userdata> TealUserdataBuilder<'a, T> {
|
||||||
V: FromLua<'a> + LuaTypeName,
|
V: FromLua<'a> + LuaTypeName,
|
||||||
T: TealUserdata + 'static
|
T: TealUserdata + 'static
|
||||||
{
|
{
|
||||||
|
let docs = self.queued_docs.take().unwrap_or_default();
|
||||||
|
|
||||||
let tname = V::get_lua_name();
|
let tname = V::get_lua_name();
|
||||||
if let Some(field) = self.fields.get_mut(&tname) {
|
if let Some(field) = self.fields.get_mut(&tname) {
|
||||||
field.can_set = true;
|
field.can_set = true;
|
||||||
|
@ -184,6 +217,7 @@ impl<'a, T: Userdata> TealUserdataBuilder<'a, T> {
|
||||||
name: tname.clone(),
|
name: tname.clone(),
|
||||||
},
|
},
|
||||||
can_set: true,
|
can_set: true,
|
||||||
|
docs,
|
||||||
};
|
};
|
||||||
|
|
||||||
self.fields.insert(tname, desc);
|
self.fields.insert(tname, desc);
|
||||||
|
@ -199,7 +233,7 @@ impl<'a, T: Userdata> TealUserdataBuilder<'a, T> {
|
||||||
A: FromLuaVec<'a> + LuaTypeName,
|
A: FromLuaVec<'a> + LuaTypeName,
|
||||||
R: AsLua<'a> + LuaTypeName,
|
R: AsLua<'a> + LuaTypeName,
|
||||||
{
|
{
|
||||||
let func_desc = function_desc::<A, R>(&mut self.func_arg_names, name);
|
let func_desc = function_desc::<A, R>(&mut self.func_arg_names, &mut self.queued_docs, name);
|
||||||
self.funcs.insert(name.to_string(), func_desc);
|
self.funcs.insert(name.to_string(), func_desc);
|
||||||
|
|
||||||
self.inner.function(name, f);
|
self.inner.function(name, f);
|
||||||
|
@ -213,7 +247,7 @@ impl<'a, T: Userdata> TealUserdataBuilder<'a, T> {
|
||||||
R: AsLua<'a> + LuaTypeName,
|
R: AsLua<'a> + LuaTypeName,
|
||||||
T: TealUserdata + 'static
|
T: TealUserdata + 'static
|
||||||
{
|
{
|
||||||
let mut func_desc = function_desc::<A, R>(&mut self.func_arg_names, name);
|
let mut func_desc = function_desc::<A, R>(&mut self.func_arg_names, &mut self.queued_docs, name);
|
||||||
let mut tmp = vec![FuncArg {
|
let mut tmp = vec![FuncArg {
|
||||||
name: Some("self".to_string()),
|
name: Some("self".to_string()),
|
||||||
ty: Type {
|
ty: Type {
|
||||||
|
@ -236,7 +270,7 @@ impl<'a, T: Userdata> TealUserdataBuilder<'a, T> {
|
||||||
R: AsLua<'a> + LuaTypeName,
|
R: AsLua<'a> + LuaTypeName,
|
||||||
T: TealUserdata + 'static
|
T: TealUserdata + 'static
|
||||||
{
|
{
|
||||||
let mut func_desc = function_desc::<A, R>(&mut self.func_arg_names, name);
|
let mut func_desc = function_desc::<A, R>(&mut self.func_arg_names, &mut self.queued_docs, name);
|
||||||
let mut tmp = vec![FuncArg {
|
let mut tmp = vec![FuncArg {
|
||||||
name: Some("self".to_string()),
|
name: Some("self".to_string()),
|
||||||
ty: Type {
|
ty: Type {
|
||||||
|
@ -260,7 +294,7 @@ impl<'a, T: Userdata> TealUserdataBuilder<'a, T> {
|
||||||
R: AsLua<'a> + LuaTypeName,
|
R: AsLua<'a> + LuaTypeName,
|
||||||
T: TealUserdata + 'static
|
T: TealUserdata + 'static
|
||||||
{
|
{
|
||||||
let mut func_desc = function_desc::<A, R>(&mut self.func_arg_names, name.as_ref());
|
let mut func_desc = function_desc::<A, R>(&mut self.func_arg_names, &mut self.queued_docs, name.as_ref());
|
||||||
let mut tmp = vec![FuncArg {
|
let mut tmp = vec![FuncArg {
|
||||||
name: Some("self".to_string()),
|
name: Some("self".to_string()),
|
||||||
ty: Type {
|
ty: Type {
|
||||||
|
|
|
@ -5,6 +5,9 @@ pub struct TypeWalker {
|
||||||
records: Vec<Record>,
|
records: Vec<Record>,
|
||||||
global_fields: Vec<FieldDesc>,
|
global_fields: Vec<FieldDesc>,
|
||||||
global_funcs: Vec<FunctionDesc>,
|
global_funcs: Vec<FunctionDesc>,
|
||||||
|
func_arg_names: Option<Vec<String>>,
|
||||||
|
/// docs that will be added to a field or function that will soon be added
|
||||||
|
queued_docs: Option<Vec<String>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TypeWalker {
|
impl TypeWalker {
|
||||||
|
@ -28,23 +31,47 @@ impl TypeWalker {
|
||||||
self.records.push(record);
|
self.records.push(record);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Add documentation for a field, or function that will added right after this
|
||||||
|
pub fn document(&mut self, text: &str) -> &mut Self {
|
||||||
|
if self.queued_docs.is_none() {
|
||||||
|
self.queued_docs = Some(Vec::default());
|
||||||
|
}
|
||||||
|
|
||||||
|
let docs = self.queued_docs.as_mut().unwrap();
|
||||||
|
docs.push(text.to_string());
|
||||||
|
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
pub fn add_global_field<T: LuaTypeName>(&mut self, name: &str) {
|
pub fn add_global_field<T: LuaTypeName>(&mut self, name: &str) {
|
||||||
|
let docs = self.queued_docs.take().unwrap_or_default();
|
||||||
|
|
||||||
let field = FieldDesc {
|
let field = FieldDesc {
|
||||||
name: name.to_string(),
|
name: name.to_string(),
|
||||||
ty: Type::new::<T>(),
|
ty: Type::new::<T>(),
|
||||||
can_set: false,
|
can_set: false,
|
||||||
|
docs,
|
||||||
};
|
};
|
||||||
|
|
||||||
self.global_fields.push(field);
|
self.global_fields.push(field);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_global_func<'a, Args, Ret>(&mut self, name: &str, arg_names: &[&str])
|
pub fn set_arg_names(&mut self, names: &[&str]) -> &mut Self {
|
||||||
|
debug_assert!(self.func_arg_names.is_none(),
|
||||||
|
"Invalid attempt to set argument names for function. \
|
||||||
|
There are arguments that are currently pending to be set on a function");
|
||||||
|
|
||||||
|
self.func_arg_names = Some(names.iter().map(|n| n.to_string()).collect());
|
||||||
|
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_global_func<'a, Args, Ret>(&mut self, name: &str)
|
||||||
where
|
where
|
||||||
Args: FromLuaVec<'a> + LuaTypeName,
|
Args: FromLuaVec<'a> + LuaTypeName,
|
||||||
Ret: AsLua<'a> + LuaTypeName
|
Ret: AsLua<'a> + LuaTypeName
|
||||||
{
|
{
|
||||||
let arg_names: Vec<_> = arg_names.iter().map(|s| s.to_string()).collect();
|
let mut desc = function_desc::<Args, Ret>(&mut self.func_arg_names, &mut self.queued_docs, name);
|
||||||
let mut desc = function_desc::<Args, Ret>(&mut Some(arg_names), name);
|
|
||||||
desc.is_field = true;
|
desc.is_field = true;
|
||||||
|
|
||||||
self.global_funcs.push(desc);
|
self.global_funcs.push(desc);
|
||||||
|
@ -86,7 +113,9 @@ mod tests {
|
||||||
let mut walker = TypeWalker::new();
|
let mut walker = TypeWalker::new();
|
||||||
walker.walk_type::<Vec3>();
|
walker.walk_type::<Vec3>();
|
||||||
walker.add_global_field::<f64>("multiplier");
|
walker.add_global_field::<f64>("multiplier");
|
||||||
walker.add_global_func::<(f32, f64, usize), i32>("do_cool_math", &["a", "b", "z"]);
|
walker.document("This function does some very cool math that does a lot.");
|
||||||
|
walker.set_arg_names(&["a", "b", "z"]);
|
||||||
|
walker.add_global_func::<(f32, f64, usize), i32>("do_cool_math");
|
||||||
|
|
||||||
println!("{}", walker.to_type_def());
|
println!("{}", walker.to_type_def());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue