first macro impl

This commit is contained in:
Robin Müller 2022-11-27 18:21:50 +01:00
parent 7062c12ef0
commit 9b37c63280
No known key found for this signature in database
GPG Key ID: BE6480244DFE612C
7 changed files with 135 additions and 5 deletions

View File

@ -25,12 +25,16 @@ impl ResultU16 {
#[derive(Debug)]
pub struct ResultU16Ext {
pub name: &'static str,
pub result: ResultU16,
pub result: &'static ResultU16,
pub info: &'static str,
}
impl ResultU16Ext {
pub const fn const_new(name: &'static str, result: ResultU16, info: &'static str) -> Self {
pub const fn const_new(
name: &'static str,
result: &'static ResultU16,
info: &'static str,
) -> Self {
Self { name, result, info }
}
}

View File

@ -1,7 +1,105 @@
use proc_macro2::{Ident, TokenStream};
use quote::{format_ident, quote, ToTokens};
use syn::spanned::Spanned;
use syn::{parse_macro_input, AttributeArgs, Item, Lit, LitStr, Meta, NestedMeta, Type};
#[derive(Default)]
struct ResultExtGenerator {
name_str: Option<Ident>,
info_str: Option<LitStr>,
}
#[proc_macro_attribute]
pub fn result(
_attr: proc_macro::TokenStream,
args: proc_macro::TokenStream,
item: proc_macro::TokenStream,
) -> proc_macro::TokenStream {
item
let args = parse_macro_input!(args as AttributeArgs);
let input = parse_macro_input!(item as Item);
dbg!("Arguments: {}", &args);
dbg!("Input: {}", &input);
let mut result_ext_generator = ResultExtGenerator::default();
result_ext_generator.parse(args, input).into()
}
impl ResultExtGenerator {
pub fn parse(&mut self, args: AttributeArgs, input: Item) -> TokenStream {
let mut output = input.to_token_stream();
if let Err(e) = self.parse_args(args) {
output.extend(e.into_compile_error());
return output;
}
match self.gen_ext_struct(input) {
Ok(ts) => output.extend(ts),
Err(e) => output.extend(e.into_compile_error()),
}
output
}
pub fn parse_args(&mut self, args: AttributeArgs) -> syn::Result<()> {
for arg in args {
if let NestedMeta::Meta(Meta::NameValue(nvm)) = arg {
if let Some(path) = nvm.path.segments.first() {
if path.ident == "info" {
if let Lit::Str(str) = nvm.lit {
self.info_str = Some(str);
} else {
return Err(syn::Error::new(
nvm.lit.span(),
"Only literal strings are allowed as information",
));
}
} else {
return Err(syn::Error::new(
path.span(),
format!(
"Unknown attribute argument name {}",
path.ident
),
));
}
}
}
}
Ok(())
}
pub fn gen_ext_struct(&mut self, input: Item) -> syn::Result<TokenStream> {
if let Item::Const(const_item) = &input {
self.name_str = Some(const_item.ident.clone());
if let Type::Path(p) = &const_item.ty.as_ref() {
let mut valid_type_found = false;
for seg in &p.path.segments {
if seg.ident == "ResultU16" {
valid_type_found = true;
}
}
if !valid_type_found {
return Err(syn::Error::new(
p.span(),
"Can only be applied on items of type ResultU16",
));
}
}
} else {
return Err(syn::Error::new(
input.span(),
"Only const items are allowed to be use with this attribute",
));
}
let result_code_name = self.name_str.to_owned().unwrap();
let name_as_str = result_code_name.to_string();
let gen_struct_name = format_ident!("{}_EXT", result_code_name);
let info_str = self.info_str.to_owned().unwrap();
let gen_struct = quote! {
const #gen_struct_name: satrs_core::resultcode::ResultU16Ext = satrs_core::resultcode::ResultU16Ext {
name: #name_as_str,
result: &#result_code_name,
info: #info_str
};
};
Ok(gen_struct)
//Ok(TokenStream::new())
}
}

7
satrs-macros/src/main.rs Normal file
View File

@ -0,0 +1,7 @@
use satrs_core::resultcode::ResultU16;
use satrs_macros::*;
#[result(info = "This is a test result where the first parameter is foo")]
const _TEST_RESULT: ResultU16 = ResultU16::const_new(0, 1);
fn main() {}

View File

@ -1,7 +1,7 @@
use satrs_core::resultcode::ResultU16;
use satrs_macros::*;
#[result]
#[result(info = "This is a test result where the first parameter is foo")]
const TEST_RESULT: ResultU16 = ResultU16::const_new(0, 1);
fn main() {}

View File

@ -0,0 +1,12 @@
use satrs_core::resultcode::ResultU16;
use satrs_macros::*;
pub enum GroupIds {
Group0 = 0,
Group1 = 1,
}
#[result(info = "This is a test result where the first parameter is foo")]
const TEST_RESULT: ResultU16 = ResultU16::const_new(GroupIds::Group0 as u8, 1);
fn main() {}

View File

@ -2,4 +2,6 @@
fn tests() {
let t = trybuild::TestCases::new();
t.pass("tests/basic.rs");
//t.pass("tests/verify_gen_struct.rs");
//t.pass("tests/group_in_enum.rs");
}

View File

@ -0,0 +1,7 @@
use satrs_core::resultcode::ResultU16;
use satrs_macros::*;
#[result(info = "This is a test result where the first parameter is foo")]
const TEST_RESULT: ResultU16 = ResultU16::const_new(0, 1);
fn main() {}