aboutsummaryrefslogtreecommitdiffstats
path: root/sylt_macro
diff options
context:
space:
mode:
Diffstat (limited to 'sylt_macro')
-rw-r--r--sylt_macro/src/lib.rs78
1 files changed, 76 insertions, 2 deletions
diff --git a/sylt_macro/src/lib.rs b/sylt_macro/src/lib.rs
index fc43b5c..3b8b37c 100644
--- a/sylt_macro/src/lib.rs
+++ b/sylt_macro/src/lib.rs
@@ -73,15 +73,89 @@ pub fn extern_function(tokens: TokenStream) -> TokenStream {
#[allow(unused_variables)]
match __values {
#(#typecheck_blocks),*
- _ => Err(sylt::error::ErrorKind::ExternTypeMismatch(stringify!(#function).to_string(), __values.iter().map(|v| sylt::Type::from(v)).collect()))
+ _ => Err(sylt::error::ErrorKind::ExternTypeMismatch(
+ stringify!(#function).to_string(),
+ __values.iter().map(|v| sylt::Type::from(v)).collect()
+ ))
}
} else {
match __values {
#(#eval_blocks),*
- _ => Err(sylt::error::ErrorKind::ExternTypeMismatch(stringify!(#function).to_string(), __values.iter().map(|v| sylt::Type::from(v)).collect()))
+ _ => Err(sylt::error::ErrorKind::ExternTypeMismatch(
+ stringify!(#function).to_string(),
+ __values.iter().map(|v| sylt::Type::from(v)).collect()
+ ))
}
}
}
};
TokenStream::from(tokens)
}
+
+struct LinkRename {
+ _as: Token![as],
+ name: syn::Ident,
+}
+
+impl Parse for LinkRename {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Ok(Self {
+ _as: input.parse()?,
+ name: input.parse()?,
+ })
+ }
+}
+
+struct Link {
+ path: syn::Path,
+ rename: Option<LinkRename>,
+}
+
+impl Parse for Link {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Ok(Self {
+ path: input.parse()?,
+ rename: input.parse().ok(),
+ })
+ }
+}
+
+struct Links {
+ links: Vec<Link>,
+}
+
+impl Parse for Links {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let mut res = Self {
+ links: Vec::new(),
+ };
+ while !input.is_empty() {
+ res.links.push(input.parse()?);
+ let _comma: Option<Token![,]> = input.parse().ok();
+ }
+ Ok(res)
+ }
+}
+
+
+#[proc_macro]
+pub fn link(tokens: TokenStream) -> TokenStream {
+ let links: Links = parse_macro_input!(tokens);
+
+ let links: Vec<_> = links.links.iter().map(|link| {
+ let name = if let Some(rename) = &link.rename {
+ &rename.name
+ } else {
+ &link.path.segments.last().unwrap().ident
+ };
+ let path = &link.path;
+ quote! {
+ (stringify!(#name).to_string(), #path)
+ }
+ }).collect();
+
+ let tokens = quote! {
+ vec![ #(#links),* ]
+ };
+ TokenStream::from(tokens)
+}