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:
parent
8421dd46b6
commit
3fae228c1a
5 changed files with 18 additions and 138 deletions
|
@ -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"
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in a new issue