code: strinto

This commit is contained in:
2024-01-26 11:27:05 +01:00
parent 9f4067e94c
commit cdfa399060
4 changed files with 124 additions and 0 deletions

62
strinto/src/lib.rs Normal file
View File

@@ -0,0 +1,62 @@
extern crate proc_macro;
use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, Expr, ExprStruct};
/// # literal strings in a struct insantiation are converted .into().
///
/// ```rust
/// use strinto::strinto;
/// #[derive(Debug)]
/// struct TestStruct {
/// name: String,
/// title: String,
/// description: String,
/// age: usize,
/// }
///
/// let descr = "description";
///
/// let output = strinto!(TestStruct {
/// name: "John", // Literal string.
/// title: String::from("Wicked"),
/// description: descr.to_string(),
/// age: 30,
/// });
///
/// let output_string = format!("{:?}", output);
/// assert_eq!(
/// output_string,
/// "TestStruct { name: \"John\", title: \"Wicked\", description: \"description\", age: 30 }"
/// );
/// ```
#[proc_macro]
pub fn strinto(input: TokenStream) -> TokenStream {
let expr_struct = parse_macro_input!(input as ExprStruct);
// Extract struct name and fields
let struct_name = &expr_struct.path;
let fields = expr_struct.fields.iter().map(|field| {
let field_name = field.member.clone();
let field_value = &field.expr;
// Determine if the field value is a string literal and transform it
if let Expr::Lit(expr_lit) = field_value {
if let syn::Lit::Str(_) = expr_lit.lit {
quote! { #field_name: #field_value.into() }
} else {
quote! { #field_name: #field_value }
}
} else {
quote! { #field_name: #field_value }
}
});
let expanded = quote! {
#struct_name {
#(#fields,)*
}
};
expanded.into()
}