Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bug: Using the serde attribute rename fails since 0.14.0 with a missing field error #522

Open
gabrielkim13 opened this issue Feb 2, 2024 · 4 comments
Labels

Comments

@gabrielkim13
Copy link

Starting at config@0.14.0, serde renamed fields are no longer supported due to the "missing field" error.


Consider the following minimal reproduceable example:

# Cargo.toml

[package]
name = "config-missing-field"
version = "0.1.0"
edition = "2021"

[dependencies]
config = { version = "0.14", default-features = false, features = ["json"] }
serde = { version = "1", features = ["derive"] }
// main.rs

use config::{Config, File, FileFormat};

#[allow(unused)]
#[derive(serde::Deserialize, Debug)]
struct MyConfig {
    #[serde(rename = "FooBar")]
    foo_bar: String,
}

fn main() {
    const MY_CONFIG: &str = r#"{
        "FooBar": "Hello, world!"
    }"#;

    let cfg = Config::builder()
        .add_source(File::from_str(MY_CONFIG, FileFormat::Json))
        .build()
        .unwrap();

    println!("{cfg:#?}");

    let my_config: MyConfig = cfg.try_deserialize().unwrap();

    // Panics at the previous instruction, with "missing field" error.

    println!("{my_config:#?}");
}

The output is as follows:

❯ cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.02s
     Running `target/debug/config-missing-field`
Config {
    defaults: {},
    overrides: {},
    sources: [],
    cache: Value {
        origin: None,
        kind: Table(
            {
                "foobar": Value {
                    origin: None,
                    kind: String(
                        "Hello, world!",
                    ),
                },
            },
        ),
    },
}
thread 'main' panicked at src/main.rs:27:53:
called `Result::unwrap()` on an `Err` value: missing field `FooBar`
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace 

Reverting the dependency back to config@0.13.4 works as expected:

❯ cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.02s
     Running `target/debug/config-missing-field`
Config {
    defaults: {},
    overrides: {},
    sources: [],
    cache: Value {
        origin: None,
        kind: Table(
            {
                "FooBar": Value {
                    origin: None,
                    kind: String(
                        "Hello, world!",
                    ),
                },
            },
        ),
    },
}
MyConfig {
    foo_bar: "Hello, world!",
} 
@matthiasbeyer
Copy link
Collaborator

Thanks for filing this!
Awesome (irony) that our tests did not find this 😢

@gabrielkim13
Copy link
Author

You're welcome! And thanks for the quick response :)

@polarathene
Copy link
Collaborator

Same bug I believe: #531

rename should work presumably if only using lowercase value? Looks like 0.14.0 has some fixes contributed that converted to lowercase that broke serde features.

@polarathene polarathene changed the title "Missing field" error when using serde's rename macro attribute bug: Using the serde attribute rename fails since 0.14.0 with a missing field error Feb 3, 2024
@Lawson-Y
Copy link

I've encountered the same issue. When using config@0.14 in combination with serde, applying #[serde(rename_all = "camelCase")] to handle the yaml configuration file does not work as expected. Below is the configuration file:

dataBase:
  url: "http://www.ss.com.cn"
  userName: "张三"
  password: "1233"
addr: "0.0.0.0:8887"
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct Conf {
    pub data_base: Option<DataBase>,
    pub addr: Option<String>,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct DataBase {
    pub url: String,
    pub user_name: String,
    pub password: String,
    #[serde(default)]
    pub data_base_connection_poll: DataBaseConnectionPool,
}

When I reverted the config to version 0.13, this code executed as expected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants