From ca9aa4b456e0a720dd461575726e56946785cfc5 Mon Sep 17 00:00:00 2001 From: Oscar Beaumont Date: Tue, 9 Jul 2024 23:39:42 +0800 Subject: [PATCH] Backport good stuff from #252 --- specta-macros/src/specta.rs | 21 +++++++++++++---- specta-typescript/src/lib.rs | 12 +++++----- specta/src/function/mod.rs | 44 ++++++++++++++++++++++++++++++------ 3 files changed, 59 insertions(+), 18 deletions(-) diff --git a/specta-macros/src/specta.rs b/specta-macros/src/specta.rs index 2e6bbf51..84cf62b8 100644 --- a/specta-macros/src/specta.rs +++ b/specta-macros/src/specta.rs @@ -42,16 +42,27 @@ pub fn attribute(item: proc_macro::TokenStream) -> syn::Result false, }; - let arg_names = function.sig.inputs.iter().map(|input| { + let mut arg_names = Vec::new(); + for input in function.sig.inputs.iter() { let arg = match input { - FnArg::Receiver(_) => unreachable!("Commands cannot take 'self'"), + FnArg::Receiver(_) => { + return Err(syn::Error::new_spanned( + input, + "functions with `#[specta]` cannot take 'self'", + )) + } FnArg::Typed(arg) => match &*arg.pat { Pat::Ident(ident) => ident.ident.to_token_stream(), Pat::Macro(m) => m.mac.tokens.to_token_stream(), Pat::Struct(s) => s.path.to_token_stream(), Pat::Slice(s) => s.attrs[0].to_token_stream(), Pat::Tuple(s) => s.elems[0].to_token_stream(), - _ => unreachable!("Commands must take named arguments"), + _ => { + return Err(syn::Error::new_spanned( + input, + "functions with `#[specta]` must take named arguments", + )) + } }, }; @@ -63,8 +74,8 @@ pub fn attribute(item: proc_macro::TokenStream) -> syn::Result, TypeMap); pub use crate::collect_functions; use crate::{DataType, DeprecatedType, TypeMap}; -// TODO: Probs move this into the `DataType` module??? +// TODO: Probs move this into the `DataType` module??? // TODO /// Contains type information about a function annotated with [`specta`](macro@crate::specta). /// Returned by [`fn_datatype`]. #[derive(Debug, Clone)] pub struct FunctionDataType { /// Whether the function is async. - pub asyncness: bool, + asyncness: bool, /// The function's name. - pub name: Cow<'static, str>, + name: Cow<'static, str>, /// The name and type of each of the function's arguments. - pub args: Vec<(Cow<'static, str>, DataType)>, + args: Vec<(Cow<'static, str>, DataType)>, /// The return type of the function. - pub result: Option, + result: Option, /// The function's documentation. Detects both `///` and `#[doc = ...]` style documentation. - pub docs: Cow<'static, str>, + docs: Cow<'static, str>, /// The deprecated status of the function. - pub deprecated: Option, + deprecated: Option, +} + +impl FunctionDataType { + pub fn asyncness(&self) -> bool { + self.asyncness + } + + pub fn name(&self) -> &Cow<'static, str> { + &self.name + } + + pub fn args(&self) -> impl Iterator, DataType)> { + self.args.iter() + } + + pub fn result(&self) -> Option<&DataType> { + self.result.as_ref() + } + + pub fn docs(&self) -> &Cow<'static, str> { + &self.docs + } + + pub fn deprecated(&self) -> Option<&DeprecatedType> { + self.deprecated.as_ref() + } } /// Implemented by functions that can be annoatated with [`specta`](crate::specta).