code: strinto
This commit is contained in:
parent
9f4067e94c
commit
cdfa399060
1
strinto/.gitignore
vendored
Normal file
1
strinto/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
/target
|
47
strinto/Cargo.lock
generated
Normal file
47
strinto/Cargo.lock
generated
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.78"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "1.0.35"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "strinto"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "2.0.48"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-ident"
|
||||||
|
version = "1.0.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
14
strinto/Cargo.toml
Normal file
14
strinto/Cargo.toml
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
[package]
|
||||||
|
name = "strinto"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
proc-macro = true
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
syn = { version = "2.0", features = ["full"] }
|
||||||
|
quote = "1.0"
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
proc-macro2 = "1.0"
|
62
strinto/src/lib.rs
Normal file
62
strinto/src/lib.rs
Normal 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()
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user