Deriving `Config` for enums
(Issue moved from here for better discussion)
@amkartashov wrote:
What about allowing to derive Config for enums? I started using your library in my project and have
oneoffields described by enums. I parse it with serde fow now, so it's a mixed approach.
@amkartashov could you describe your use case in more detail? Maybe some example code how you wish confique would work?
Thanks @LukasKalbertodt My usecase is to support mutually exclusive sections in config file. I'm writing app which can use different backend types, so it can store blobs on a filesystem or in KV storage or something else.
In config it looks like this (filesystem as backend):
backend:
actions:
module: fs
options:
path: /tmp/cache/ac
blobs:
module: fs
options:
path: /tmp/cache/cas
max_chunk_size: 10000000
or like this (GRPC service as backend for actions, TiKV as backend for blobs)
backend:
actions:
module: grpc
options:
url: grpc://localhost:8980
blobs:
module: tikv
options:
db_url: ...
max_chunk_size: 10000000
As of now, I use serde to parse config file:
#[derive(Debug, Deserialize, Config, Clone)]
pub struct Conf {
...
#[config(nested)]
pub backend: BackendConf,
}
#[derive(Debug, Deserialize, Config, Clone)]
pub struct BackendConf {
...
pub actions: Option<ActionStorageConf>,
pub blobs: Option<BlobStorageConf>,
}
#[derive(Debug, Deserialize, Clone)]
#[serde(tag = "module", content = "options")]
pub enum ActionStorageConf {
#[serde(alias = "fs")]
FS(FsActionStorageConf),
...
}
#[derive(Debug, Deserialize, Clone)]
#[serde(tag = "module", content = "options")]
pub enum BlobStorageConf {
#[serde(alias = "fs")]
FS(FsBlobStorageConf),
...
}
#[derive(Debug, Deserialize, Clone)]
pub struct FsActionStorageConf {
pub path: PathBuf,
}
#[derive(Debug, Deserialize, Clone)]
pub struct FsBlobStorageConf {
pub path: PathBuf,
#[serde(default = "default_fs_blob_max_chunk_size")]
pub max_chunk_size: usize,
}
So basically, it works this far with serde, but I can't use confique features like using env vars for example.
Thanks for the example! Seems like a useful feature to me. Is probably related to #14. I will dig into this in the future, trying to come up with a nice API. But no promises as to when. For now I'm happy with 0.2.0. Of course if you want to, you can suggest a specific way confique would derive Config for enums (as comment first, no need to implement it already).
Require this (specifically tagging stuff) before I can adopt this crate. Here's some examples of our enums:
#[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
#[serde(
untagged,
expecting = "expected a project name or dependency config object"
)]
pub enum ProjectDependsOn {
String(ProjectID),
Object(DependencyConfig),
}
#[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
#[serde(
untagged,
expecting = "expected a sequence of globs or a map of projects"
)]
pub enum WorkspaceProjects {
Both {
globs: Vec<FileGlob>,
sources: ProjectsMap,
},
Globs(Vec<FileGlob>),
Sources(ProjectsMap),
}