0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-11-25 16:22:35 +01:00

ircd::conf: Develop conf get/set by string; use mapping by item name.

This commit is contained in:
Jason Volk 2018-03-02 03:03:33 -08:00
parent 51a3e0f33b
commit f8e356eb0e
2 changed files with 111 additions and 27 deletions

View file

@ -19,8 +19,15 @@ namespace ircd::conf
template<> struct item<seconds>;
IRCD_EXCEPTION(ircd::error, error)
IRCD_EXCEPTION(error, not_found)
IRCD_EXCEPTION(error, bad_value)
extern const std::string &config; //TODO: X
extern const std::string &config; //TODO: X
extern std::map<string_view, item<> *> items;
string_view get(const string_view &key, const mutable_buffer &out);
bool set(const string_view &key, const string_view &value);
bool set(std::nothrow_t, const string_view &key, const string_view &value);
void init(const string_view &configfile);
}
@ -29,15 +36,17 @@ namespace ircd::conf
/// derived templates instead.
template<>
struct ircd::conf::item<void>
:instance_list<ircd::conf::item<>>
{
json::strung feature_;
json::object feature;
string_view name;
virtual bool refresh();
virtual string_view get(const mutable_buffer &) const;
virtual bool set(const string_view &);
item(const json::members &);
item(item &&) = delete;
item(const item &) = delete;
virtual ~item() noexcept;
};
@ -46,39 +55,40 @@ struct ircd::conf::item<void>
/// conf items which contain similar classes of values.
template<class T>
struct ircd::conf::value
:conf::item<>
{
using value_type = T;
T _value;
std::function<bool (T &)> refresher;
operator const T &() const
{
return _value;
}
bool refresh() override
{
return refresher? refresher(_value) : false;
}
template<class U>
value(const json::members &memb, U&& t)
:conf::item<>{memb}
,_value{std::forward<U>(t)}
{}
value(const json::members &memb = {})
:conf::item<>{memb}
,_value{feature.get<T>("default", T{})}
template<class... A>
value(A&&... a)
:_value{std::forward<A>(a)...}
{}
};
template<>
struct ircd::conf::item<ircd::seconds>
:conf::value<seconds>
:conf::item<>
,conf::value<seconds>
{
using value_type = seconds;
using value::value;
string_view get(const mutable_buffer &out) const override
{
return lex_cast(_value, out);
}
bool set(const string_view &s) override
{
_value = lex_cast<seconds>(s);
return true;
}
item(const json::members &memb)
:conf::item<>{memb}
,value{feature.get("default", 0L)}
{}
};

View file

@ -40,13 +40,69 @@ ircd::conf::init(const string_view &filename)
_config = read_json_file(filename);
}
ircd::string_view
ircd::conf::get(const string_view &key,
const mutable_buffer &out)
try
{
const auto &item(*items.at(key));
return item.get(out);
}
catch(const std::out_of_range &e)
{
throw not_found
{
"Conf item '%s' is not available", key
};
}
bool
ircd::conf::set(std::nothrow_t,
const string_view &key,
const string_view &value)
try
{
return set(key, value);
}
catch(const std::exception &e)
{
log::error
{
"%s", e.what()
};
return false;
}
bool
ircd::conf::set(const string_view &key,
const string_view &value)
try
{
auto &item(*items.at(key));
return item.set(value);
}
catch(const bad_lex_cast &e)
{
throw bad_value
{
"Conf item '%s' rejected value '%s'", key, value
};
}
catch(const std::out_of_range &e)
{
throw not_found
{
"Conf item '%s' is not available", key
};
}
//
// item
//
template<>
decltype(ircd::instance_list<ircd::conf::item<>>::list)
ircd::instance_list<ircd::conf::item<>>::list
decltype(ircd::conf::items)
ircd::conf::items
{};
/// Conf item abstract constructor.
@ -61,22 +117,40 @@ ircd::conf::item<void>::item(const json::members &opts)
}
,name
{
feature.has("name")? unquote(feature["name"]) : "<unnamed>"_sv
unquote(feature.at("name"))
}
{
if(!items.emplace(name, this).second)
throw error
{
"Conf item named '%s' already exists", name
};
}
ircd::conf::item<void>::~item()
noexcept
{
if(name)
{
const auto it{items.find(name)};
assert(data(it->first) == data(name));
items.erase(it);
}
}
bool
ircd::conf::item<void>::refresh()
ircd::conf::item<void>::set(const string_view &)
{
return false;
}
ircd::string_view
ircd::conf::item<void>::get(const mutable_buffer &)
const
{
return {};
}
//
// misc
//