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

Support Enum? #74

Closed
quake opened this issue Jul 6, 2018 · 10 comments · Fixed by #119
Closed

Support Enum? #74

quake opened this issue Jul 6, 2018 · 10 comments · Fixed by #119
Labels

Comments

@quake
Copy link

quake commented Jul 6, 2018

Got this error when try it with config-rs:

Err(invalid type: string "master", expected enum Mode)

Below is the struct and toml file:

#[derive(Debug, Deserialize)]
struct Database {
    url: String,
    mode: Mode,
}

#[derive(Debug, Deserialize)]
enum Mode {
    Master,
    Slave,
}
[database]
url = "postgres://postgres@localhost"
mode = "master"

toml supports Enum
toml-rs/toml-rs#165

am I doing anything wrong?

@mehcode
Copy link
Collaborator

mehcode commented Sep 26, 2018

It just seems that we don't support it on our end probably due to oversight. This would be a bug that needs fixing.

@mehcode mehcode added the C-bug label Sep 26, 2018
@mehcode mehcode added this to the 0.10.0 milestone Oct 5, 2018
@vorner
Copy link
Contributor

vorner commented Oct 17, 2018

I've hit this too and tried to report it to serde (because to me it looked like the generated Deserialize must have been wrong).

Anyway, I also have a workaround, look here ‒ the trick with flattening another structure in. I don't know why it helps yet, though.

@mehcode
Copy link
Collaborator

mehcode commented Oct 17, 2018

Huh. The code path for flatten might be strange. It's definitely our fault for the normal case though. Enums are handled different in the deserializer and we just are missing that.

@vorner
Copy link
Contributor

vorner commented Dec 30, 2018

I just wanted to ask, if the code is in master now, would it make sense to release it as part of 0.9.2, not waiting for full 0.10.0?

@mehcode mehcode removed this from the 0.10.0 milestone Jan 3, 2019
@mehcode
Copy link
Collaborator

mehcode commented Jan 3, 2019

Released as 0.9.2

@mehcode mehcode closed this as completed Jan 3, 2019
@vorner
Copy link
Contributor

vorner commented Jan 8, 2019

This seems not to work fully yet, this still fails :-( :

use std::collections::HashMap;
use config::{Config, File, FileFormat};
use serde::Deserialize;

#[derive(Debug, Eq, PartialEq, Hash, Deserialize)]
enum X {
    A,
    B,
}

const CFG: &str = r#"
A = "hello"
B = "world"
"#;

fn main() {
    let mut config = Config::new();
    config.merge(File::from_str(CFG, FileFormat::Toml)).unwrap();
    let c: HashMap<X, String> = config.try_into().unwrap();
}
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: invalid type: string "b", expected enum X', src/libcore/result.rs:999:5

By the way… should I open a separate issue for the fact it tries to feed it with lower-case b instead of the B I put into the configuration? (but it still fails even if I rename the enum to accept lower-case version).

It does seem to work in value-position in a struct, though.

Can we reopen? Or should I open a new one?

@geniusisme
Copy link
Contributor

Enums as keys are not supported yet and I doubt they will ever be. Configuration sources are transformed into simple intermediate representation, which is tree built of maps/arrays and strings/numbers as leafs. And keys can only be strings in these maps. Then this intermediate representation is transformed into whatever you ask, within certain limits imposed by simple config structure.

Enums with trivial constructors can be deserialized from string values with corresponding names. More complex enums are deserialized from config maps/arrays, as everything else.

If you want to get complex data structures deserialized from config, you will need to do additional work. In your example it is possible to get Map<String, String> first, and then simply deserialize enum from string.

With regards to lower-case - here is the issue about that #65

@vorner
Copy link
Contributor

vorner commented Jan 8, 2019

Right, I'm only interest in the case where it is a simple enum, without any carried data ‒ I just want to limit the choices of what might be used as the key. That sounds like something that should be possible in theory (the complex enums as keys is probably not possible because it doesn't make sense in the tree structure).

@vorner
Copy link
Contributor

vorner commented Jan 8, 2019

By the way, I discovered a workaround that works now (without additional post-processing of the config data structure). I can first try_into into a serde_json::Value and go from there.

@mehcode mehcode reopened this Jan 10, 2019
@mehcode
Copy link
Collaborator

mehcode commented Jan 10, 2019

Hm.. enums as configuration keys is a bit out-of-scope but I think we could make it work though. I'll leave this open to think through that.

vorner added a commit to vorner/config-rs that referenced this issue Aug 5, 2019
(Currently failing)

Related to rust-cli#74
vorner added a commit to vorner/config-rs that referenced this issue Aug 5, 2019
vorner added a commit to vorner/config-rs that referenced this issue Aug 5, 2019
(Currently failing)

Related to rust-cli#74
vorner added a commit to vorner/config-rs that referenced this issue Aug 5, 2019
@vorner vorner mentioned this issue Aug 5, 2019
vorner added a commit to vorner/config-rs that referenced this issue Aug 22, 2019
Of particular interest are maps that have numbers or enums as keys.

Closes rust-cli#74.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants