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:
parent
51a3e0f33b
commit
f8e356eb0e
2 changed files with 111 additions and 27 deletions
|
@ -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)}
|
||||
{}
|
||||
};
|
||||
|
|
84
ircd/conf.cc
84
ircd/conf.cc
|
@ -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
|
||||
//
|
||||
|
|
Loading…
Reference in a new issue