Flow 1.0.0
Flow project: Public API.
Public Types | Public Member Functions | Related Functions | List of all members
flow::cfg::Static_config_manager< Value_set > Class Template Reference

A Config_manager-related adapter-style class that manages a simple config setup involving a single (though arbitrarily complex) Option_set<>-ready raw value struct config store type Value_set, meant to be used only in static fashion. More...

#include <static_cfg_manager.hpp>

Inheritance diagram for flow::cfg::Static_config_manager< Value_set >:
[legend]
Collaboration diagram for flow::cfg::Static_config_manager< Value_set >:
[legend]

Public Types

enum  allow_invalid_defaults_tag_t { S_ALLOW_INVALID_DEFAULTS }
 Tag type: indicates an apply() method must allow invalid defaults and only complain if the config source does not explicitly supply a valid value. More...
 
using Impl = Config_manager< Value_set, Null_value_set >
 The class we privately subclass (in HAS-A fashion, not IS-A fashion). More...
 

Public Member Functions

 Static_config_manager (log::Logger *logger_ptr, util::String_view nickname, typename Option_set< Value_set >::Declare_options_func &&declare_opts_func_moved)
 Constructs a Static_config_manager ready to read static config via apply() and access it via values(). More...
 
bool apply (const fs::path &cfg_path, const typename Final_validator_func< Value_set >::Type &final_validator_func)
 Invoke this after construction to load the permanent set of static config from config sources including a static config file. More...
 
bool apply (allow_invalid_defaults_tag_t, const fs::path &cfg_path, const typename Final_validator_func< Value_set >::Type &final_validator_func)
 Identical to similar apply() overload without allow_invalid_defaults_tag_t tag; but skips the stringent check on individual defaults' validity. More...
 
bool apply (const fs::path &cfg_path)
 Equivalent to the other apply() but with no inter-option validation (meaning the per-option validation passed to constructor is sufficient). More...
 
bool apply (allow_invalid_defaults_tag_t, const fs::path &cfg_path)
 Identical to similar apply() overload without allow_invalid_defaults_tag_t tag; but skips the stringent check on individual defaults' validity. More...
 
const Value_set & values () const
 Returns (always the same) reference to the managed Value_set structure. More...
 

Related Functions

(Note that these are not member functions.)

template<typename Value_set >
std::ostream & operator<< (std::ostream &os, const Static_config_manager< Value_set > &val)
 Serializes (briefly) a Static_config_manager to a standard output stream. More...
 

Detailed Description

template<typename Value_set>
class flow::cfg::Static_config_manager< Value_set >

A Config_manager-related adapter-style class that manages a simple config setup involving a single (though arbitrarily complex) Option_set<>-ready raw value struct config store type Value_set, meant to be used only in static fashion.

That is to say, the parsed config values are not meant to be accessed while the config is being read from file.

If you desire dynamic config (which can be read from file(s) at any time), and/or you need to manage more than one config struct (e.g., you're controlling 2+ entirely separate modules), then please use Config_manager which supports all that. (You can also develop your own handling of Option_set<Value_set> instead. See Config_manager doc header.)

The life cycle and usage are simple. Define your Value_set (see Option_set doc header for formal requirements, but basically you'll need a struct, an option-defining function using FLOW_CFG_OPTION_SET_DECLARE_OPTION(), and possibly an inter-option validator function). Construct the Static_config_manager<Value_set>. Call apply() to read a file. (You can do this more than once, potentially for different files. As of this writing only files are supported, but adding command line parsing would be an incremental change.) Then, call values() to get the reference to the immutable parsed Value_set. This reference can be passed around the application; values() will always return the same reference. Technically you could call apply() even after using values(); but it is not thread-safe to do so while accessing config values which would change concurrently with no protection.

Also you may create a const (immutable) Static_config_manager via its constructor and then just use it to output a help message (log_help() or help_to_ostream()). This could be used with your program's --help option or similar, and that's it (no parsing takes place).

// Example of a Static_config_manager created just to log the help, and that's it.
(get_logger(), "cfg", &static_cfg_declare_opts)
.log_help();
A Config_manager-related adapter-style class that manages a simple config setup involving a single (t...
Definition: static_cfg_manager.hpp:81
Logger * get_logger() const
Returns the stored Logger pointer, particularly as many FLOW_LOG_*() macros expect.
Definition: log.cpp:224
Note
Config_manager provides the optional commit == false mode in apply_static(); this enables the "multi-source parsing and source skipping" described in its doc header. Static_config_manager, to keep its mission simple, cuts off access to this feature, meaning implicitly it always takes commit to equal true. That is, it is expected you'll be loading static config from exactly one file/one apply() call per attempt. Your Final_validator_func::Type final_validator_func() should return either Final_validator_outcome::S_ACCEPT or Final_validator_outcome::S_FAIL. It can return Final_validator_outcome::S_SKIP, but that would mean apply() will return true (success) but simply no-op (not update the canonical config as returned by values()).

Rationale

Config_manager is in the author's opinion not difficult to use, but it does use template parameter packs (typename... Value_set), and its API can be somewhat difficult to grok when all you have is the aforementioned simple use case.

Template Parameters
Value_setThe settings struct – see Option_set doc header for requirements.

Member Typedef Documentation

◆ Impl

template<typename Value_set >
using flow::cfg::Static_config_manager< Value_set >::Impl = Config_manager<Value_set, Null_value_set>

The class we privately subclass (in HAS-A fashion, not IS-A fashion).

It is public basically so that we can refer to it in various forwarding using method directives below.

Member Enumeration Documentation

◆ allow_invalid_defaults_tag_t

Tag type: indicates an apply() method must allow invalid defaults and only complain if the config source does not explicitly supply a valid value.

Otherwise the defaults themselves are also stringently checked regardless of whether they are overridden. This setting applies only to individual-option-validators. Final_validator_func validation is orthogonal to this.

Enumerator
S_ALLOW_INVALID_DEFAULTS 

Sole value for tag type allow_invalid_defaults_tag_t.

Constructor & Destructor Documentation

◆ Static_config_manager()

template<typename Value_set >
flow::cfg::Static_config_manager< Value_set >::Static_config_manager ( log::Logger logger_ptr,
util::String_view  nickname,
typename Option_set< Value_set >::Declare_options_func &&  declare_opts_func_moved 
)
explicit

Constructs a Static_config_manager ready to read static config via apply() and access it via values().

Logging assumption

*logger_ptr is a standard logging arg. Note, though, that the class will assume that log verbosity may not have yet been configured – since this Static_config_manager may be the thing configuring it. Informal recommendations:

  • You should let through INFO and WARNING messages in *logger_ptr.
  • If you plan to use *this only for log_help() (such as in your --help implementation), you should not let through TRACE-or-more-verbose.
  • Once (and if) you engage any actual parsing (apply()), TRACE may be helpful in debugging as usual.
Parameters
logger_ptrLogger to use for subsequently logging.
nicknameBrief string used for logging subsequently.
declare_opts_func_movedThe declare-options callback as required by Option_set<Value_set> constructor; see its doc header for instructions.

Member Function Documentation

◆ apply() [1/4]

template<typename Value_set >
bool flow::cfg::Static_config_manager< Value_set >::apply ( allow_invalid_defaults_tag_t  ,
const fs::path &  cfg_path 
)

Identical to similar apply() overload without allow_invalid_defaults_tag_t tag; but skips the stringent check on individual defaults' validity.

See also
allow_invalid_defaults_tag_t doc header and/or return-value doc just below.
Parameters
cfg_pathSee other apply().
Returns
See other apply(). However the latter will return false if a default is invalid, even if file cfg_path explicitly sets it to a valid value. This tagged overload will not.

◆ apply() [2/4]

template<typename Value_set >
bool flow::cfg::Static_config_manager< Value_set >::apply ( allow_invalid_defaults_tag_t  ,
const fs::path &  cfg_path,
const typename Final_validator_func< Value_set >::Type &  final_validator_func 
)

Identical to similar apply() overload without allow_invalid_defaults_tag_t tag; but skips the stringent check on individual defaults' validity.

See also
allow_invalid_defaults_tag_t doc header and/or return-value doc just below.
Parameters
cfg_pathSee other apply().
final_validator_funcSee other apply().
Returns
See other apply(). However the latter will return false if a default is invalid, even if file cfg_path explicitly sets it to a valid value. This tagged overload will not.

◆ apply() [3/4]

template<typename Value_set >
bool flow::cfg::Static_config_manager< Value_set >::apply ( const fs::path &  cfg_path)

Equivalent to the other apply() but with no inter-option validation (meaning the per-option validation passed to constructor is sufficient).

See also apply() overload with allow_invalid_defaults_tag_t tag.

Parameters
cfg_pathFile to read.
Returns
true if and only if successfully parsed config source(s) and validated all settings; and defaults were also all individually valid.

◆ apply() [4/4]

template<typename Value_set >
bool flow::cfg::Static_config_manager< Value_set >::apply ( const fs::path &  cfg_path,
const typename Final_validator_func< Value_set >::Type &  final_validator_func 
)

Invoke this after construction to load the permanent set of static config from config sources including a static config file.

See also apply() overload with allow_invalid_defaults_tag_t tag.

After this runs and succeeds, you may use values() to access the loaded values (but see notes on final_validator_func arg and return value, regarding Final_validator_outcome::S_SKIP w/r/t final_validator_func arg).

On failure returns false; else returns true. In the former case the overall state is equal to that at entry to the method. Tip: On failure you may want to exit program with error; or you can continue knowing that values() will return default values according to Value_set() no-arg ctor. WARNING(s) logged given failure.

Before apply(), or after it fails, the contents of what values() returns will be the defaults from your Value_set structure in its constructed state. This may or may not have utility depending on your application.

apply() will not be tolerant of unknown option names appearing in the config source.

Note
final_validator_func() can be made quite brief by using convenience macro FLOW_CFG_OPT_CHECK_ASSERT(). This will take care of most logging in most cases.
Todo:
Add support for command line as a config source in addition to file(s), for static config in cfg::Config_manager.
Parameters
cfg_pathFile to read.
final_validator_funcIf parsing and individual-option-validation succeed, the method shall return success if final_validator_func(V) returns Final_validator_outcome::S_ACCEPT or Final_validator_outcome::S_SKIP, where V is the parsed Value_set; and in the former case values() post-this-method will return V. Informally: Please place individual-option validation into FLOW_CFG_OPTION_SET_DECLARE_OPTION() invocations; only use final_validator_func() for internal consistency checks (if any). Informally: It is unlikely, with Static_config_manager, that it should return SKIP; that feature is only useful with the multi-file-update feature which is not accessible through Static_config_manager. See the note about this in our class doc header.
Returns
true if and only if successfully parsed config source and validated all settings including final_validator_func() != S_FAIL; and defaults were also all individually valid. If true, and final_validator_func() == S_ACCEPT, then values() shall return the parsed Value_set. If true, but final_validator_func() == S_SKIP, then values() shall return the default-cted Value_set

◆ values()

template<typename Value_set >
const Value_set & flow::cfg::Static_config_manager< Value_set >::values

Returns (always the same) reference to the managed Value_set structure.

Before successful apply() these values will be at their defaults. Tip: It should be sufficient to pass around only the const ref obtained here all around the app – no Value_set copying should be needed.

Returns
See above. To reiterate: always the same reference is returned.

Friends And Related Function Documentation

◆ operator<<()

template<typename Value_set >
std::ostream & operator<< ( std::ostream &  os,
const Static_config_manager< Value_set > &  val 
)
related

Serializes (briefly) a Static_config_manager to a standard output stream.

Template Parameters
Value_setSee Static_config_manager doc header.
Parameters
osStream to which to serialize.
valValue to serialize.
Returns
os.

The documentation for this class was generated from the following files: