ores.cpp.service-app.config_options_header

Table of Contents

Option declarations. component-service profile.

A service that adds an option of its own declares the member here: <<paste:0B222F2C-B8B6-41AE-AF03-C61D76AF6833>> sits after the standard database member. Supply it as a #+begin_src cpp :name service_app_config_option :implements 0B222F2C-B8B6-41AE-AF03-C61D76AF6833 block on the service's component_overview.org; the option's command-line declaration and its assignment belong to the config_parser_impl archetype.

The options print through the JSON codec, so the struct states its wire shape. A service that declares a member of its own names it in the shape as well: <<paste:656876C4-82D2-4D19-928C-681CAF5C115C>> sits after the standard database field. Supply it as a #+begin_src cpp :name service_app_config_option_field :implements 656876C4-82D2-4D19-928C-681CAF5C115C block holding one ::ores::utility::codec::field line per member. The static_assert beside the shape stops the build when a member has no field.

See the Template variable reference for the complete list of available variables and their semantics.

1. Template

The full template source. Edit here and re-tangle with compass build --direct tangle_codegen_templates to regenerate library/templates/cpp_service_config_options.hpp.mustache.

{{! GENERATED FILE — tangled from projects/ores.codegen/library/templates/cpp_service_app.org. Edit the org source. }}
{{{cpp_license}}}
{{#component}}
#ifndef {{full_name_upper}}_CONFIG_OPTIONS_HPP
#define {{full_name_upper}}_CONFIG_OPTIONS_HPP

#include <iosfwd>
#include <optional>
#include <tuple>
{{#has_service_options}}
#include <cstdint>
#include <string>
{{/has_service_options}}
#include "ores.logging/logging_options.hpp"
#include "ores.database/domain/database_options.hpp"
#include "ores.nats/config/nats_options.hpp"
#include "ores.utility/codec/member_count.hpp"
#include "ores.utility/codec/wire_fields.hpp"

namespace {{namespace}}::config {

/**
 * @brief All of the configuration options required by the service.
 */
struct options final {
    /**
     * @brief Configuration options related to logging, if any.
     */
    std::optional<ores::logging::logging_options> logging;
    /**
     * @brief Configuration related to NATS transport.
     */
    ores::nats::config::nats_options nats;
    /**
     * @brief Configuration related to database operations.
     */
    ores::database::database_options database;
{{#service_options}}
    /**
{{#doc_lines}}
     *{{#.}} {{{.}}}{{/.}}
{{/doc_lines}}
     */
    {{{cpp_type}}} {{name}}{{#initial}}{ {{{initial}}} }{{/initial}};
{{/service_options}}
<<paste:0B222F2C-B8B6-41AE-AF03-C61D76AF6833>>
};

[[nodiscard]] constexpr auto wire_fields(std::type_identity<options>) {
    return std::tuple{
        ::ores::utility::codec::field{"logging", &options::logging},
        ::ores::utility::codec::field{"nats", &options::nats},
        ::ores::utility::codec::field{"database", &options::database},
{{#service_options}}
{{^secret}}
        ::ores::utility::codec::field{"{{name}}", &options::{{name}}},
{{/secret}}
{{/service_options}}
<<paste:656876C4-82D2-4D19-928C-681CAF5C115C>>
    };
}

static_assert(::ores::utility::codec::names_every_member<options>({{#has_service_secrets}}{{service_secret_count}}{{/has_service_secrets}}),
              "options has a member its wire shape does not name");

std::ostream& operator<<(std::ostream& s, const options& v);

}

#endif
{{/component}}

2. See also

Emacs 29.3 (Org mode 9.6.15)