kamchatka-volcano / figcone

Read JSON, YAML, TOML, XML or INI configuration by declaring a struct
Microsoft Public License
102 stars 2 forks source link

YAML support for include files and/or custom tags #14

Closed MeanSquaredError closed 1 year ago

MeanSquaredError commented 1 year ago

Hi, This is more of a suggestion/feature request, rather than a bug report.

In some cases it makes sense for two or more applications to share parts of their configurations. The easiest way to achieve that is through support for YAML include files, where each of the main config files includes a file that contains the shared part of the configuration.

It seems that YAML does not have standard support for includes, but some YAML parsers add support for non-standard include tags. Other parsers support callbacks for unrecognized YAML tags, which allows the user to implement custom support for includes.

figcone relies on rapidyaml, so the feasibility of the implementation of such an include mechanism and/or custom tags really depends on rapidyaml, but it will be great to have support for includes and/or custom tags.

I think that the same is true for the other supported file formats (JSON, TOML, etc), but I am using mostly YAML, so that is why I put YAML into the subject.

kamchatka-volcano commented 1 year ago

Hi! figcone is intended to be an interface for a common feature set across multiple config formats, so I'm not planning to add anything that can only be used with YAML. However, the idea of supporting callbacks is actually great. I believe I've heard of a callback interface in XML parsers, but I've never used one, and I haven't considered incorporating something like that into figcone. I think it can be used to replicate the functionality you're talking about. In fact, in my similar library for command line parsing, cmdlime, a post processor can be registered to apply some final changes to the config object, and I believe it could do the job:

struct CommonCfg : figcone::Config{
    FIGCONE_PARAM(data, std::string);
};

struct Cfg : figcone::Config{    
    CommonCfg common; //not registered with figcone    
    FIGCONE_PARAM(commonDataFile, fs::path);               
};

namespace figcone{
template<>
struct PostProcessor<Cfg> {
    void operator()(Cfg& cfg)
    {
        cfg.common = figcone::ConfigReader{}.readYaml<CommonCfg>(cfg.commonDataFile);
    }
};
}

int main()
{
    auto cfg = figcone::ConfigReader{}.readYaml<Cfg>(R"(
        commonData: ~/common_data.yml
    )");    
    use(cfg.common);
}

Note that you have to use regular syntax that maps to figcone params and nodes, as I mentioned YAML tags won't be supported. I typically mirror all functionality related to config registration between cmdlime and figcone, so, I would add the PostProcessor to figcone sooner or later. Please let me know if this solution would be useful to you so that I can give it a higher priority.

MeanSquaredError commented 1 year ago

Thank you for the information. For the time being I decided to allow one of the programs access to the configuration file of the other program, which should take care of sharing configuration data between the two programs. So there is no urgent need to add PostProcessor to figcone.

Thank you for developing and maintaining figcone, it is really useful!