mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-23 00:00:33 +00:00
88 lines
2.7 KiB
Rust
88 lines
2.7 KiB
Rust
use proc_macro::TokenStream;
|
|
use quote::quote;
|
|
use syn::{parse_macro_input, ItemStruct, Lit, Type};
|
|
|
|
fn is_bool_type(ty: &Type) -> bool {
|
|
if let Type::Path(type_path) = ty {
|
|
if let Some(segment) = type_path.path.segments.last() {
|
|
return segment.ident == "bool";
|
|
}
|
|
}
|
|
false
|
|
}
|
|
|
|
#[proc_macro_attribute]
|
|
pub fn annotations(attr: TokenStream, item: TokenStream) -> TokenStream {
|
|
let input = parse_macro_input!(item as ItemStruct);
|
|
let name = input.ident.clone();
|
|
|
|
// Separate fields by type
|
|
let mut bool_fields = Vec::new();
|
|
let mut custom_fields = Vec::new();
|
|
|
|
for field in input.fields.iter() {
|
|
let field_name = field.ident.clone().unwrap();
|
|
let field_type = &field.ty;
|
|
|
|
if is_bool_type(field_type) {
|
|
bool_fields.push(field_name);
|
|
} else {
|
|
custom_fields.push((field_name, field_type));
|
|
}
|
|
}
|
|
let (custom_field_names, custom_field_types): (Vec<_>, Vec<_>) =
|
|
custom_fields.into_iter().unzip();
|
|
|
|
// Parse comment literal
|
|
let comm_lit = match parse_macro_input!(attr as Lit) {
|
|
Lit::Str(lit_str) => lit_str.value(),
|
|
_ => panic!("Expected a string literal"),
|
|
};
|
|
|
|
TokenStream::from(quote! {
|
|
#[derive(Default, Debug, Copy, Clone)]
|
|
#input
|
|
|
|
impl #name {
|
|
/// Autogenerated by windmill-macros
|
|
pub fn parse(code: &str) -> Self {
|
|
let mut res = Self::default();
|
|
|
|
let mut lines = code.lines();
|
|
|
|
while let Some(line) = lines.next() {
|
|
if line.trim().is_empty() {
|
|
continue;
|
|
}
|
|
if !line.starts_with(#comm_lit) {
|
|
break;
|
|
}
|
|
let line = line[#comm_lit.len()..].trim();
|
|
let (key, value) = line.split_once('=').unwrap_or((line, ""));
|
|
|
|
match key {
|
|
#(
|
|
stringify!(#custom_field_names) => {
|
|
if value.is_empty() {
|
|
continue;
|
|
}
|
|
res.#custom_field_names = #custom_field_types::parse(value);
|
|
}
|
|
)*
|
|
#(
|
|
stringify!(#bool_fields) => {
|
|
res.#bool_fields = true;
|
|
}
|
|
)*
|
|
_ => {
|
|
// Unknown key=value annotation
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
res
|
|
}
|
|
}
|
|
})
|
|
}
|