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

ircd::json: Simplify json::object interface: eliminate path traversing overloads.

This commit is contained in:
Jason Volk 2019-01-12 16:32:17 -08:00
parent 8421dd46b6
commit 3fae228c1a
5 changed files with 18 additions and 138 deletions

View file

@ -50,7 +50,6 @@ namespace ircd::json
} }
#include "util.h" #include "util.h"
#include "path.h"
#include "array.h" #include "array.h"
#include "object.h" #include "object.h"
#include "vector.h" #include "vector.h"

View file

@ -52,9 +52,7 @@ namespace ircd::json
/// Recursive traversal cannot be achieved via a single key string value; so /// Recursive traversal cannot be achieved via a single key string value; so
/// any string_view argument for a key will not be recursive. In other words, /// any string_view argument for a key will not be recursive. In other words,
/// due to the fact that a JS identifier can have almost any character we have /// due to the fact that a JS identifier can have almost any character we have
/// to use a different *type* like a vector of strings; in our common case we /// to use a different *type* like a vector of strings.
/// use an initializer_list typedef'ed as `path` and those overloads will be
/// recursive.
/// ///
struct ircd::json::object struct ircd::json::object
:string_view :string_view
@ -85,21 +83,16 @@ struct ircd::json::object
size_t count() const; size_t count() const;
size_t size() const; // warns if used; use count() size_t size() const; // warns if used; use count()
bool has(const string_view &key) const; bool has(const string_view &key) const;
bool has(const path &) const;
// returns value or default // returns value or default
template<class T> T get(const string_view &key, const T &def = T{}) const; template<class T> T get(const string_view &key, const T &def = T{}) const;
template<class T> T get(const path &, const T &def = T{}) const;
string_view get(const string_view &key, const string_view &def = {}) const; string_view get(const string_view &key, const string_view &def = {}) const;
string_view get(const path &, const string_view &def = {}) const;
// returns value or throws not_found // returns value or throws not_found
template<class T = string_view> T at(const string_view &key) const; template<class T = string_view> T at(const string_view &key) const;
template<class T = string_view> T at(const path &) const;
// returns value or empty // returns value or empty
string_view operator[](const string_view &key) const; string_view operator[](const string_view &key) const;
string_view operator[](const path &) const;
// constructor. Note that you are able to construct from invalid JSON. The // constructor. Note that you are able to construct from invalid JSON. The
// parser is not invoked until other operations and that's when it errors. // parser is not invoked until other operations and that's when it errors.
@ -178,13 +171,6 @@ struct ircd::json::object::const_iterator
friend bool operator>(const const_iterator &, const const_iterator &); friend bool operator>(const const_iterator &, const const_iterator &);
}; };
inline ircd::string_view
ircd::json::object::operator[](const path &path)
const
{
return get(path);
}
inline ircd::string_view inline ircd::string_view
ircd::json::object::operator[](const string_view &key) ircd::json::object::operator[](const string_view &key)
const const
@ -193,38 +179,6 @@ const
return it != end()? it->second : string_view{}; return it != end()? it->second : string_view{};
} }
template<class T>
T
ircd::json::object::at(const path &path)
const try
{
object object(*this);
const auto it(std::find_if(std::begin(path), std::end(path), [&object]
(const string_view &key)
{
const auto it(object.find(key));
if(it == std::end(object))
throw not_found
{
"'%s'", key
};
object = it->second;
return false;
}));
return lex_cast<T>(object);
}
catch(const bad_lex_cast &e)
{
throw type_error
{
"'%s' must cast to type %s",
ircd::string(path),
typeid(T).name()
};
}
template<ircd::json::name_hash_t key, template<ircd::json::name_hash_t key,
class T> class T>
T T
@ -274,14 +228,6 @@ catch(const bad_lex_cast &e)
}; };
} }
inline ircd::string_view
ircd::json::object::get(const path &path,
const string_view &def)
const
{
return get<string_view>(path, def);
}
inline ircd::string_view inline ircd::string_view
ircd::json::object::get(const string_view &key, ircd::json::object::get(const string_view &key,
const string_view &def) const string_view &def)
@ -290,31 +236,6 @@ const
return get<string_view>(key, def); return get<string_view>(key, def);
} }
template<class T>
T
ircd::json::object::get(const path &path,
const T &def)
const try
{
object object(*this);
const auto it(std::find_if(std::begin(path), std::end(path), [&object]
(const string_view &key)
{
const auto it(object.find(key));
if(it == std::end(object))
return true;
object = it->second;
return false;
}));
return it == std::end(path)? lex_cast<T>(object) : def;
}
catch(const bad_lex_cast &e)
{
return def;
}
template<ircd::json::name_hash_t key, template<ircd::json::name_hash_t key,
class T> class T>
ircd::string_view ircd::string_view
@ -389,26 +310,6 @@ const
return sv.size() <= 2; return sv.size() <= 2;
} }
inline bool
ircd::json::object::has(const path &path)
const
{
object object(*this);
const auto it(std::find_if(std::begin(path), std::end(path), [&object]
(const string_view &key)
{
const auto val(object[key]);
if(val.empty())
return true;
object = val;
return false;
}));
// && path.size() ensures false for empty path.
return it == std::end(path) && path.size();
}
inline bool inline bool
ircd::json::object::has(const string_view &key) ircd::json::object::has(const string_view &key)
const const

View file

@ -1,35 +0,0 @@
// Matrix Construct
//
// Copyright (C) Matrix Construct Developers, Authors & Contributors
// Copyright (C) 2016-2018 Jason Volk <jason@zemos.net>
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice is present in all copies. The
// full license for this software is available in the LICENSE file.
#pragma once
#define HAVE_IRCD_JSON_PATH_H
namespace ircd::json
{
/// Higher order type beyond a string to cleanly delimit multiple keys.
using path = std::initializer_list<string_view>;
std::ostream &operator<<(std::ostream &, const path &);
}
inline std::ostream &
ircd::json::operator<<(std::ostream &s, const path &p)
{
auto it(std::begin(p));
if(it != std::end(p))
{
s << *it;
++it;
}
for(; it != std::end(p); ++it)
s << '.' << *it;
return s;
}

View file

@ -1272,9 +1272,14 @@ ircd::m::v1::fetch_head(const id::room &room_id,
request.in.content request.in.content
}; };
const json::object event
{
proto.at("event")
};
const json::array prev_events const json::array prev_events
{ {
proto.at({"event", "prev_events"}) event.at("prev_events")
}; };
const json::array prev_event const json::array prev_event

View file

@ -123,9 +123,19 @@ init_my_tls_crt()
const json::object config{}; const json::object config{};
if(!fs::exists(cert_file)) if(!fs::exists(cert_file))
{ {
const json::object &certificate
{
config.get("certificate")
};
const json::object &self_
{
certificate.get(m::self::origin)
};
std::string subject std::string subject
{ {
config.get({"certificate", m::self::origin, "subject"}) self_.get("subject")
}; };
if(!subject) if(!subject)