commonsensesoftware / more-rs-config

Rust Configuration Framework
MIT License
3 stars 2 forks source link

Enum deserialization doesn't work properly #19

Open 4oooo4 opened 2 months ago

4oooo4 commented 2 months ago

example.json

{ 
  "Name": "some name", 
  "Enums": [
    "First",
    {
      "Second": "test"
    }
  ]
}

main.rs

use config::{ext::*, *};
use serde::Deserialize;
use std::fs::File;
use std::io::BufReader;

#[derive(Debug, Deserialize)]
#[serde(rename_all(deserialize = "PascalCase"))]
pub struct MyStruct {
    pub name: String,
    pub enums: Box<[MyEnum]>
}

#[derive(Debug, Deserialize)]
enum MyEnum {
    First,
    Second(String),
}

fn main() {
    let file = File::open("example.json").unwrap();
    let reader = BufReader::new(file);
    let my_struct_from_serde: MyStruct = serde_json::from_reader(reader).unwrap();
    println!("{my_struct_from_serde:#?}");

    let config = DefaultConfigurationBuilder::new()
        .add_json_file("example.json")
        .build()
        .unwrap();

    let my_struct_from_config: MyStruct = config.reify();
    println!("{my_struct_from_config:#?}");
}

Result: my_struct_from_serde deserialized correctly, my_struct_from_config panicked.

MyStruct {
    name: "some name",
    enums: [
        First,
        Second(
            "test",
        ),
    ],
}

thread 'main' panicked at /home/user/.cargo/registry/src/index.crates.io-6f17d22bba15001f/more-config-2.1.4/binder.rs:42:32:
called `Result::unwrap()` on an `Err` value: Custom("unknown variant ``, expected `First` or `Second`")
stack backtrace:
   0: rust_begin_unwind
             at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/panicking.rs:665:5
   1: core::panicking::panic_fmt
             at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/core/src/panicking.rs:74:14
   2: core::result::unwrap_failed
             at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/core/src/result.rs:1679:5
   3: core::result::Result<T,E>::unwrap
             at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/core/src/result.rs:1102:23
   4: <dyn config::configuration::Configuration as config::binder::ConfigurationBinder>::reify
             at /home/user/.cargo/registry/src/index.crates.io-6f17d22bba15001f/more-config-2.1.4/binder.rs:42:9
   5: gateway::main
             at ./src/main.rs:44:43
   6: core::ops::function::FnOnce::call_once
             at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/core/src/ops/function.rs:250:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

Process finished with exit code 101

The issue is in this enum value:

{
   "Second": "test"
}

when i remove it then everything works as expected.

commonsensesoftware commented 2 weeks ago

Apologies for the long, overdue acknowledgement. Yes, this is a bug. deserialize_enum currently only handles scalar values. To properly support all enum variant types. This requires implementing EnumAccess. It's achievable, but it's non-trivial. This scenario should be supported if people want to use enumerations this way.