aboutsummaryrefslogtreecommitdiffstats
path: root/sylt_macro/src
diff options
context:
space:
mode:
authorGustav Sörnäs <gustav@sornas.net>2021-02-22 11:39:42 +0100
committerGustav Sörnäs <gustav@sornas.net>2021-02-22 11:39:42 +0100
commit5449818b0975341e03720a450eec877453dee7c4 (patch)
treeb6df2df8fee78972f9a1fd3578a4f8a643bc614e /sylt_macro/src
parent3715433024e2df742a6ad16488ab2a580e397b86 (diff)
downloadsylt-5449818b0975341e03720a450eec877453dee7c4.tar.gz
Squash-merge remote tracking branch 'origin/automatic-link'
Diffstat (limited to 'sylt_macro/src')
-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)
+}