0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-11-29 18:22:50 +01:00

ircd:Ⓜ️ Begin an event::errors fundamental conformity report.

This commit is contained in:
Jason Volk 2018-02-20 18:09:39 -08:00
parent 1bf9997086
commit c72f7f1e96
2 changed files with 171 additions and 0 deletions

View file

@ -64,6 +64,7 @@ struct ircd::m::event
{
struct prev;
struct fetch;
struct errors;
// Common convenience aliases
using id = m::id::event;
@ -128,3 +129,40 @@ struct ircd::m::event::fetch
friend bool seek(fetch &, const event::id &, std::nothrow_t);
friend void seek(fetch &, const event::id &);
};
struct ircd::m::event::errors
{
enum code :uint;
uint64_t report {0};
bool clean() const;
operator bool() const;
bool operator!() const;
bool has(const uint &code) const;
bool has(const code &code) const;
string_view string(const mutable_buffer &out) const;
void set(const code &code);
void del(const code &code);
errors() = default;
errors(const event &);
friend string_view reflect(const code &);
friend std::ostream &operator<<(std::ostream &, const errors &);
};
enum ircd::m::event::errors::code
:uint
{
INVALID_EVENT_ID,
INVALID_ROOM_ID,
INVALID_SENDER_ID,
INVALID_REDACTS_ID,
INVALID_TYPE,
DEPTH_NEGATIVE,
DEPTH_ZERO_NON_CREATE,
_NUM_
};

View file

@ -501,3 +501,136 @@ const
{
return row.valid(event_id);
}
//
// event::errors
//
namespace ircd::m
{
const size_t event_errors_num{num_of<event::errors::code>()};
extern const std::array<string_view, event_errors_num> event_errors_reflects;
}
decltype(ircd::m::event_errors_reflects)
ircd::m::event_errors_reflects
{
"INVALID_EVENT_ID",
"INVALID_ROOM_ID",
"INVALID_SENDER_ID",
"INVALID_REDACTS_ID",
"DEPTH_NEGATIVE",
"DEPTH_ZERO_NON_CREATE",
};
std::ostream &
ircd::m::operator<<(std::ostream &s, const event::errors &errors)
{
thread_local char buf[1024];
s << errors.string(buf);
return s;
}
ircd::string_view
ircd::m::reflect(const event::errors::code &code)
try
{
return event_errors_reflects.at(code);
}
catch(const std::out_of_range &e)
{
return "??????"_sv;
}
ircd::m::event::errors::errors(const event &e)
:report{0}
{
if(!valid(m::id::EVENT, json::get<"event_id"_>(e)))
set(INVALID_EVENT_ID);
if(!valid(m::id::ROOM, json::get<"room_id"_>(e)))
set(INVALID_ROOM_ID);
if(!valid(m::id::USER, json::get<"sender"_>(e)))
set(INVALID_SENDER_ID);
if(json::get<"type"_>(e) == "m.room.redaction")
if(!valid(m::id::EVENT, json::get<"redacts"_>(e)))
set(INVALID_REDACTS_ID);
//TODO: XXX
if(empty(json::get<"type"_>(e)))
set(INVALID_TYPE);
if(json::get<"depth"_>(e) < 0)
set(DEPTH_NEGATIVE);
if(json::get<"type"_>(e) != "m.room.create")
if(json::get<"depth"_>(e) == 0)
set(DEPTH_ZERO_NON_CREATE);
}
void
ircd::m::event::errors::del(const code &code)
{
report &= ~(1UL << code);
}
void
ircd::m::event::errors::set(const code &code)
{
report |= (1UL << code);
}
ircd::string_view
ircd::m::event::errors::string(const mutable_buffer &out)
const
{
mutable_buffer buf{out};
for(uint64_t i(0); i < num_of<code>(); ++i)
{
if(!has(code(i)))
continue;
if(begin(buf) != begin(out))
consume(buf, copy(buf, " "_sv));
consume(buf, copy(buf, reflect(code(i))));
}
return { data(out), begin(buf) };
}
bool
ircd::m::event::errors::has(const code &code)
const
{
return report & (1UL << code);
}
bool
ircd::m::event::errors::has(const uint &code)
const
{
return (report & (1UL << code)) == code;
}
bool
ircd::m::event::errors::operator!()
const
{
return clean();
}
ircd::m::event::errors::operator bool()
const
{
return !clean();
}
bool
ircd::m::event::errors::clean()
const
{
return report == 0;
}