mirror of
https://github.com/matrix-construct/construct
synced 2025-01-13 08:23:56 +01:00
ircd::json: Reduce iov interface; make conditional nodes evaluate conditionally.
This commit is contained in:
parent
f1443752c5
commit
5146ddf67e
2 changed files with 114 additions and 75 deletions
|
@ -45,6 +45,7 @@ struct ircd::json::iov
|
|||
struct set_if;
|
||||
struct defaults;
|
||||
struct defaults_if;
|
||||
using conditional_member = std::pair<string_view, std::function<json::value ()>>;
|
||||
|
||||
IRCD_EXCEPTION(json::error, error);
|
||||
IRCD_EXCEPTION(error, exists);
|
||||
|
@ -71,10 +72,8 @@ struct ircd::json::iov::push
|
|||
operator const member &() const;
|
||||
operator member &();
|
||||
|
||||
push(iov &iov, member m)
|
||||
:node(iov, std::move(m))
|
||||
{}
|
||||
|
||||
push(iov &, const bool &, const conditional_member &);
|
||||
push(iov &iov, member m);
|
||||
push() = default;
|
||||
};
|
||||
|
||||
|
@ -82,51 +81,29 @@ struct ircd::json::iov::push
|
|||
struct ircd::json::iov::add
|
||||
:protected ircd::json::iov::node
|
||||
{
|
||||
add(iov &, const bool &, const conditional_member &);
|
||||
add(iov &, member);
|
||||
add() = default;
|
||||
};
|
||||
|
||||
/// iov::add only if the bool argument is true for your condition
|
||||
struct ircd::json::iov::add_if
|
||||
:protected ircd::json::iov::node
|
||||
{
|
||||
add_if(iov &, const bool &, const string_view &, const std::function<json::value ()> &);
|
||||
add_if(iov &, const bool &, member);
|
||||
add_if() = default;
|
||||
};
|
||||
|
||||
/// Add or overwrite a member in the object vector.
|
||||
struct ircd::json::iov::set
|
||||
:protected ircd::json::iov::node
|
||||
{
|
||||
set(iov &, const bool &, const conditional_member &);
|
||||
set(iov &, member);
|
||||
set() = default;
|
||||
};
|
||||
|
||||
/// iov::set only if the bool argument is true for your condition
|
||||
struct ircd::json::iov::set_if
|
||||
:protected ircd::json::iov::node
|
||||
{
|
||||
set_if(iov &, const bool &, member);
|
||||
set_if() = default;
|
||||
};
|
||||
|
||||
/// Add member to the object vector if doesn't exist; otherwise ignored
|
||||
struct ircd::json::iov::defaults
|
||||
:protected ircd::json::iov::node
|
||||
{
|
||||
defaults(iov &, bool, const conditional_member &);
|
||||
defaults(iov &, member);
|
||||
defaults() = default;
|
||||
};
|
||||
|
||||
/// iov::defaults only if the bool argument is true for your condition
|
||||
struct ircd::json::iov::defaults_if
|
||||
:protected ircd::json::iov::node
|
||||
{
|
||||
defaults_if(iov &, const bool &, member);
|
||||
defaults_if() = default;
|
||||
};
|
||||
|
||||
inline ircd::json::iov::push::operator
|
||||
ircd::json::member &()
|
||||
{
|
||||
|
|
154
ircd/json.cc
154
ircd/json.cc
|
@ -1041,6 +1041,31 @@ const
|
|||
});
|
||||
}
|
||||
|
||||
ircd::json::iov::push::push(iov &iov,
|
||||
member member)
|
||||
:node
|
||||
{
|
||||
iov, std::move(member)
|
||||
}
|
||||
{
|
||||
}
|
||||
|
||||
ircd::json::iov::push::push(iov &iov,
|
||||
const bool &b,
|
||||
const conditional_member &cp)
|
||||
:node
|
||||
{
|
||||
b?
|
||||
&iov:
|
||||
nullptr,
|
||||
|
||||
b?
|
||||
member{cp.first, cp.second()}:
|
||||
member{}
|
||||
}
|
||||
{
|
||||
}
|
||||
|
||||
ircd::json::iov::add::add(iov &iov,
|
||||
member member)
|
||||
:node
|
||||
|
@ -1048,8 +1073,11 @@ ircd::json::iov::add::add(iov &iov,
|
|||
iov, [&iov, &member]
|
||||
{
|
||||
if(iov.has(member.first))
|
||||
throw exists("failed to add member '%s': already exists",
|
||||
string_view{member.first});
|
||||
throw exists
|
||||
{
|
||||
"failed to add member '%s': already exists",
|
||||
string_view{member.first}
|
||||
};
|
||||
|
||||
return std::move(member);
|
||||
}()
|
||||
|
@ -1057,32 +1085,38 @@ ircd::json::iov::add::add(iov &iov,
|
|||
{
|
||||
}
|
||||
|
||||
ircd::json::iov::add_if::add_if(iov &iov,
|
||||
const bool &b,
|
||||
member member)
|
||||
ircd::json::iov::add::add(iov &iov,
|
||||
const bool &b,
|
||||
const conditional_member &cp)
|
||||
:node
|
||||
{
|
||||
iov, std::move(member)
|
||||
b?
|
||||
&iov:
|
||||
nullptr,
|
||||
|
||||
[&iov, &b, &cp]
|
||||
{
|
||||
if(!b)
|
||||
return member{};
|
||||
|
||||
if(iov.has(cp.first))
|
||||
throw exists
|
||||
{
|
||||
"failed to add member '%s': already exists",
|
||||
string_view{cp.first}
|
||||
};
|
||||
|
||||
return member
|
||||
{
|
||||
cp.first, cp.second()
|
||||
};
|
||||
}()
|
||||
}
|
||||
{
|
||||
if(!b)
|
||||
iov.pop_front();
|
||||
}
|
||||
|
||||
ircd::json::iov::add_if::add_if(iov &iov,
|
||||
const bool &b,
|
||||
const string_view &key,
|
||||
const std::function<json::value ()> &val)
|
||||
:node
|
||||
{
|
||||
iov, b? member{key, val()} : member{}
|
||||
}
|
||||
{
|
||||
if(!b)
|
||||
iov.pop_front();
|
||||
}
|
||||
|
||||
ircd::json::iov::set::set(iov &iov, member member)
|
||||
ircd::json::iov::set::set(iov &iov,
|
||||
member member)
|
||||
:node
|
||||
{
|
||||
iov, [&iov, &member]
|
||||
|
@ -1098,48 +1132,76 @@ ircd::json::iov::set::set(iov &iov, member member)
|
|||
{
|
||||
}
|
||||
|
||||
ircd::json::iov::set_if::set_if(iov &iov,
|
||||
const bool &b,
|
||||
member member)
|
||||
ircd::json::iov::set::set(iov &iov,
|
||||
const bool &b,
|
||||
const conditional_member &cp)
|
||||
:node
|
||||
{
|
||||
iov, std::move(member)
|
||||
b?
|
||||
&iov:
|
||||
nullptr,
|
||||
|
||||
[&iov, &b, &cp]
|
||||
{
|
||||
if(!b)
|
||||
return member{};
|
||||
|
||||
iov.remove_if([&cp](const auto &existing)
|
||||
{
|
||||
return string_view{existing.first} == cp.first;
|
||||
});
|
||||
|
||||
return member
|
||||
{
|
||||
cp.first, cp.second()
|
||||
};
|
||||
}()
|
||||
}
|
||||
{
|
||||
if(!b)
|
||||
iov.pop_front();
|
||||
}
|
||||
|
||||
ircd::json::iov::defaults::defaults(iov &iov,
|
||||
member member)
|
||||
:node
|
||||
{
|
||||
iov, std::move(member)
|
||||
!iov.has(member.first)?
|
||||
&iov:
|
||||
nullptr,
|
||||
|
||||
std::move(member)
|
||||
}
|
||||
{
|
||||
const auto count
|
||||
{
|
||||
std::count_if(std::begin(iov), std::end(iov), [&member]
|
||||
(const auto &existing)
|
||||
{
|
||||
return string_view{existing.first} == string_view{member.first};
|
||||
})
|
||||
};
|
||||
|
||||
if(count > 1)
|
||||
iov.pop_front();
|
||||
}
|
||||
|
||||
ircd::json::iov::defaults_if::defaults_if(iov &iov,
|
||||
const bool &b,
|
||||
member member)
|
||||
ircd::json::iov::defaults::defaults(iov &iov,
|
||||
bool b,
|
||||
const conditional_member &cp)
|
||||
:node
|
||||
{
|
||||
iov, std::move(member)
|
||||
[&iov, &b, &cp]() -> json::iov *
|
||||
{
|
||||
if(!b)
|
||||
return nullptr;
|
||||
|
||||
if(!iov.has(cp.first))
|
||||
return &iov;
|
||||
|
||||
b = false;
|
||||
return nullptr;
|
||||
}(),
|
||||
|
||||
[&iov, &b, &cp]
|
||||
{
|
||||
if(!b)
|
||||
return member{};
|
||||
|
||||
return member
|
||||
{
|
||||
cp.first, cp.second()
|
||||
};
|
||||
}()
|
||||
}
|
||||
{
|
||||
if(!b)
|
||||
iov.pop_front();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
|
Loading…
Reference in a new issue