Skip to content

Commit 2f74642

Browse files
committed
Implement rename attribute for enums
1 parent c57814f commit 2f74642

File tree

2 files changed

+30
-6
lines changed

2 files changed

+30
-6
lines changed

econf-derive/src/lib.rs

+18-6
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use proc_macro::TokenStream;
44

55
use proc_macro2::{Ident, TokenStream as TokenStream2};
66
use quote::quote;
7-
use syn::{parse_macro_input, Data, DeriveInput, Field, Fields, LitStr};
7+
use syn::{parse_macro_input, Attribute, Data, DeriveInput, Field, Fields, LitStr, Variant};
88

99
#[proc_macro_derive(LoadEnv, attributes(econf))]
1010
pub fn load_env(input: TokenStream) -> TokenStream {
@@ -37,9 +37,9 @@ fn is_skip(f: &Field) -> bool {
3737
})
3838
}
3939

40-
fn find_renaming(f: &Field) -> Option<String> {
40+
fn find_renaming(attrs: &[Attribute]) -> Option<String> {
4141
let mut rename = None;
42-
for attr in &f.attrs {
42+
for attr in attrs {
4343
if attr.path().is_ident("econf") {
4444
attr.parse_nested_meta(|meta| {
4545
if meta.path.is_ident("rename") {
@@ -56,6 +56,14 @@ fn find_renaming(f: &Field) -> Option<String> {
5656
rename
5757
}
5858

59+
fn find_field_renaming(f: &Field) -> Option<String> {
60+
find_renaming(&f.attrs)
61+
}
62+
63+
fn find_variant_renaming(v: &Variant) -> Option<String> {
64+
find_renaming(&v.attrs)
65+
}
66+
5967
fn content(name: &Ident, data: &Data) -> TokenStream2 {
6068
match data {
6169
Data::Struct(data) => match &data.fields {
@@ -67,7 +75,7 @@ fn content(name: &Ident, data: &Data) -> TokenStream2 {
6775
#ident: self.#ident,
6876
};
6977
}
70-
match find_renaming(f) {
78+
match find_field_renaming(f) {
7179
Some(overwritten_name) => quote! {
7280
#ident: self.#ident.load(&(path.to_owned() + "_" + #overwritten_name), loader),
7381
},
@@ -89,7 +97,7 @@ fn content(name: &Ident, data: &Data) -> TokenStream2 {
8997
if is_skip(f) {
9098
return quote! { self.#i, };
9199
}
92-
match find_renaming(f) {
100+
match find_field_renaming(f) {
93101
Some(overwritten_name) => quote! {
94102
self.#i.load(&(path.to_owned() + "_" + #overwritten_name), loader),
95103
},
@@ -114,7 +122,11 @@ fn content(name: &Ident, data: &Data) -> TokenStream2 {
114122
});
115123

116124
let enums0 = data.variants.iter().map(|_| &name);
117-
let enums1 = data.variants.iter().map(|f| &f.ident);
125+
let enums1 = data.variants.iter().map(|f| {
126+
find_variant_renaming(f)
127+
.map(|overwritten_name| Ident::new(&overwritten_name, f.ident.span()))
128+
.unwrap_or_else(|| f.ident.clone())
129+
});
118130
let enums2 = data.variants.iter().map(|f| &f.ident);
119131

120132
quote! {

econf/tests/basics.rs

+12
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use econf::LoadEnv;
2+
use log::*;
23
use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, LinkedList, VecDeque};
34
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
45
use std::path::PathBuf;
@@ -361,33 +362,44 @@ struct NestedRenamed {
361362
s: String,
362363
}
363364

365+
#[derive(Debug, Eq, PartialEq, LoadEnv)]
366+
enum EnumRenamed {
367+
V1,
368+
#[econf(rename = "example_3")]
369+
V2,
370+
}
371+
364372
#[derive(LoadEnv)]
365373
struct Renamed {
366374
v1: bool,
367375
#[econf(rename = "example_1")]
368376
v2: u32,
369377
#[econf(rename = "example_2")]
370378
v3: NestedRenamed,
379+
v4: EnumRenamed,
371380
}
372381

373382
#[test]
374383
fn renamed() {
375384
std::env::set_var("RENAMED_V1", "true");
376385
std::env::set_var("RENAMED_EXAMPLE_1", "42");
377386
std::env::set_var("RENAMED_EXAMPLE_2_S", "renamed text");
387+
std::env::set_var("RENAMED_V4", "example_3");
378388

379389
let a = Renamed {
380390
v1: false,
381391
v2: 0,
382392
v3: NestedRenamed {
383393
s: "initial".to_string(),
384394
},
395+
v4: EnumRenamed::V1,
385396
};
386397

387398
let a = econf::load(a, "renamed");
388399
assert_eq!(a.v1, true);
389400
assert_eq!(a.v2, 42);
390401
assert_eq!(a.v3.s, "renamed text".to_string());
402+
assert_eq!(a.v4, EnumRenamed::V2);
391403
}
392404

393405
#[derive(LoadEnv)]

0 commit comments

Comments
 (0)