Last active
March 23, 2018 16:00
-
-
Save markand/45c9f6a3f9239802850badd8869117e3 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <type_traits> | |
#include <json.hpp> | |
class parser { | |
public: | |
template <typename Type> | |
class result; | |
private: | |
nlohmann::json json_; | |
public: | |
inline parser(nlohmann::json json) noexcept | |
: json_(std::move(json)) | |
{ | |
} | |
template <typename Type> | |
result<Type> get(const std::string& key) const noexcept | |
{ | |
auto it = json_.find(key); | |
if (it != json_.end()) | |
return result<Type>(json_[key]); | |
return result<Type>(nullptr); | |
} | |
}; | |
template <typename Type> | |
class parser_traits : public std::false_type { | |
}; | |
template <> | |
class parser_traits<std::string> : public std::true_type { | |
public: | |
static bool is_valid(const nlohmann::json& value) noexcept | |
{ | |
return value.is_string(); | |
} | |
static std::string get(const nlohmann::json& value) noexcept | |
{ | |
return value.get<std::string>(); | |
} | |
}; | |
template <typename Type> | |
class parser::result { | |
private: | |
static_assert(parser_traits<Type>::value, "type not supported"); | |
Type result_; | |
bool valid_{false}; | |
public: | |
inline result(const nlohmann::json& value) noexcept | |
{ | |
if (parser_traits<Type>::is_valid(value)) { | |
result_ = parser_traits<Type>::get(value); | |
valid_ = true; | |
} | |
} | |
template <typename Exception, typename... Args> | |
inline result& error(Args&&... args) | |
{ | |
if (!valid_) | |
throw Exception(std::forward<Args>(args)...); | |
return *this; | |
} | |
inline result& optional(const Type& def) | |
{ | |
if (!valid_) { | |
valid_ = true; | |
result_ = def; | |
} | |
return *this; | |
} | |
inline result& optional(Type&& def) | |
{ | |
if (!valid_) { | |
valid_ = true; | |
result_ = std::move(def); | |
} | |
return *this; | |
} | |
operator Type() const | |
{ | |
if (!valid_) | |
throw std::runtime_error("invalid value"); | |
return result_; | |
} | |
}; | |
#include <iostream> | |
class server { | |
public: | |
void set_host(std::string) {} | |
void set_port(std::string) {} | |
}; | |
int main() | |
{ | |
const nlohmann::json json{ | |
{ "hostname", "localhost" } | |
}; | |
const parser ps(json); | |
server s; | |
s.set_host(ps.get<std::string>("hostname") | |
.error<std::invalid_argument>("invalid hostname")); | |
s.set_port(ps.get<std::string>("port") | |
.optional("irc") | |
.error<std::runtime_error>("invalid port number")); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment