mirror of
https://github.com/XRPLF/rippled.git
synced 2026-07-24 07:30:30 +00:00
make TER changes
This commit is contained in:
@@ -643,44 +643,149 @@ class CanCvtToTER<NotTEC> : public std::true_type
|
||||
{
|
||||
};
|
||||
|
||||
// TER allows all of the subsets.
|
||||
using TER = TERSubset<CanCvtToTER>;
|
||||
// TERRaw allows all of the subsets (the plain numeric code, no reason string).
|
||||
using TERRaw = TERSubset<CanCvtToTER>;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Forward declaration required by TER constructors below (TER.cpp provides the
|
||||
// definition). The full public declaration is repeated after the struct.
|
||||
std::string
|
||||
transHuman(TERRaw code);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// TER: a transaction result code paired with a human-readable reason string.
|
||||
//
|
||||
// When no reason is supplied the standard description from transHuman() is used
|
||||
// automatically, so existing "return tesSUCCESS;" and "return tecNO_DST;"
|
||||
// call sites continue to compile and gain a default reason for free.
|
||||
//
|
||||
// To attach a more specific reason at a particular return site write:
|
||||
// return {tecNO_DST, "destination account has been deleted"};
|
||||
//
|
||||
struct TER
|
||||
{
|
||||
TERRaw code;
|
||||
std::string reason;
|
||||
|
||||
// Default-construct to tesSUCCESS with its standard description.
|
||||
TER() : code(tesSUCCESS), reason(transHuman(TERRaw{tesSUCCESS}))
|
||||
{
|
||||
}
|
||||
|
||||
TER(TER const&) = default;
|
||||
TER(TER&&) = default;
|
||||
TER&
|
||||
operator=(TER const&) = default;
|
||||
TER&
|
||||
operator=(TER&&) = default;
|
||||
|
||||
// --- construction from TERRaw ---
|
||||
|
||||
// Without explicit reason: populate from transHuman.
|
||||
TER(TERRaw c) : code(c), reason(transHuman(c)) // NOLINT(google-explicit-constructor)
|
||||
{
|
||||
}
|
||||
|
||||
// With explicit reason.
|
||||
TER(TERRaw c, std::string r) : code(c), reason(std::move(r))
|
||||
{
|
||||
}
|
||||
|
||||
// --- construction from any TE*codes enum or NotTEC ---
|
||||
|
||||
// Without explicit reason: populate from transHuman.
|
||||
template <typename T>
|
||||
TER(T c) // NOLINT(google-explicit-constructor)
|
||||
requires(CanCvtToTER<std::remove_cv_t<std::remove_reference_t<T>>>::value)
|
||||
: code(c), reason(transHuman(TERRaw{c}))
|
||||
{
|
||||
}
|
||||
|
||||
// With explicit reason.
|
||||
template <typename T>
|
||||
TER(T c, std::string r)
|
||||
requires(CanCvtToTER<std::remove_cv_t<std::remove_reference_t<T>>>::value)
|
||||
: code(c), reason(std::move(r))
|
||||
{
|
||||
}
|
||||
|
||||
// Build from a raw integer (used by transCode).
|
||||
static TER
|
||||
fromInt(int from)
|
||||
{
|
||||
return TER(TERRaw::fromInt(from));
|
||||
}
|
||||
|
||||
// True when the code is anything other than tesSUCCESS.
|
||||
explicit
|
||||
operator bool() const
|
||||
{
|
||||
return static_cast<bool>(code);
|
||||
}
|
||||
|
||||
// Allow assignment to json::Objects without casting.
|
||||
operator json::Value() const // NOLINT(google-explicit-constructor)
|
||||
{
|
||||
return json::Value{TERtoInt(code)};
|
||||
}
|
||||
|
||||
// Allow implicit conversion to TERRaw for backward compatibility with
|
||||
// functions that now take TERRaw (like transResultInfo, transToken, etc).
|
||||
operator TERRaw() const // NOLINT(google-explicit-constructor)
|
||||
{
|
||||
return code;
|
||||
}
|
||||
|
||||
friend std::ostream&
|
||||
operator<<(std::ostream& os, TER const& rhs)
|
||||
{
|
||||
return os << TERtoInt(rhs.code);
|
||||
}
|
||||
};
|
||||
|
||||
// Expose the underlying integer so the existing template comparison operators
|
||||
// (operator==, !=, <, <=, >, >=) continue to work with TER values.
|
||||
inline TERUnderlyingType
|
||||
TERtoInt(TER const& v)
|
||||
{
|
||||
return TERtoInt(v.code);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
inline bool
|
||||
isTelLocal(TER x) noexcept
|
||||
isTelLocal(TER const& x) noexcept
|
||||
{
|
||||
return (x >= telLOCAL_ERROR && x < temMALFORMED);
|
||||
}
|
||||
|
||||
inline bool
|
||||
isTemMalformed(TER x) noexcept
|
||||
isTemMalformed(TER const& x) noexcept
|
||||
{
|
||||
return (x >= temMALFORMED && x < tefFAILURE);
|
||||
}
|
||||
|
||||
inline bool
|
||||
isTefFailure(TER x) noexcept
|
||||
isTefFailure(TER const& x) noexcept
|
||||
{
|
||||
return (x >= tefFAILURE && x < terRETRY);
|
||||
}
|
||||
|
||||
inline bool
|
||||
isTerRetry(TER x) noexcept
|
||||
isTerRetry(TER const& x) noexcept
|
||||
{
|
||||
return (x >= terRETRY && x < tesSUCCESS);
|
||||
}
|
||||
|
||||
inline bool
|
||||
isTesSuccess(TER x) noexcept
|
||||
isTesSuccess(TER const& x) noexcept
|
||||
{
|
||||
// Makes use of TERSubset::operator bool()
|
||||
// Makes use of TER::operator bool()
|
||||
return !x;
|
||||
}
|
||||
|
||||
inline bool
|
||||
isTecClaim(TER x) noexcept
|
||||
isTecClaim(TER const& x) noexcept
|
||||
{
|
||||
return (x >= tecCLAIM);
|
||||
}
|
||||
@@ -689,13 +794,13 @@ std::unordered_map<TERUnderlyingType, std::pair<char const* const, char const* c
|
||||
transResults();
|
||||
|
||||
bool
|
||||
transResultInfo(TER code, std::string& token, std::string& text);
|
||||
transResultInfo(TERRaw code, std::string& token, std::string& text);
|
||||
|
||||
std::string
|
||||
transToken(TER code);
|
||||
transToken(TERRaw code);
|
||||
|
||||
std::string
|
||||
transHuman(TER code);
|
||||
transHuman(TERRaw code);
|
||||
|
||||
std::optional<TER>
|
||||
transCode(std::string const& token);
|
||||
|
||||
@@ -233,7 +233,7 @@ transResults()
|
||||
}
|
||||
|
||||
bool
|
||||
transResultInfo(TER code, std::string& token, std::string& text)
|
||||
transResultInfo(TERRaw code, std::string& token, std::string& text)
|
||||
{
|
||||
auto& results = transResults();
|
||||
|
||||
@@ -248,7 +248,7 @@ transResultInfo(TER code, std::string& token, std::string& text)
|
||||
}
|
||||
|
||||
std::string
|
||||
transToken(TER code)
|
||||
transToken(TERRaw code)
|
||||
{
|
||||
std::string token;
|
||||
std::string text;
|
||||
@@ -257,7 +257,7 @@ transToken(TER code)
|
||||
}
|
||||
|
||||
std::string
|
||||
transHuman(TER code)
|
||||
transHuman(TERRaw code)
|
||||
{
|
||||
std::string token;
|
||||
std::string text;
|
||||
|
||||
@@ -235,12 +235,52 @@ struct TER_test : public beast::unit_test::Suite
|
||||
testIterate<kHiIndex, kHiIndex, CheckComparable>(kTers, *this);
|
||||
}
|
||||
|
||||
void
|
||||
testReason()
|
||||
{
|
||||
testcase("Reason");
|
||||
|
||||
// 1. Implicit conversion from enum uses transHuman
|
||||
{
|
||||
TER t = tecNO_DST;
|
||||
BEAST_EXPECT(t.code == tecNO_DST);
|
||||
BEAST_EXPECT(t.reason == transHuman(TERRaw{tecNO_DST}));
|
||||
}
|
||||
|
||||
// 2. Explicit reason
|
||||
{
|
||||
TER t = {tecNO_DST, "custom reason"};
|
||||
BEAST_EXPECT(t.code == tecNO_DST);
|
||||
BEAST_EXPECT(t.reason == "custom reason");
|
||||
}
|
||||
|
||||
// 3. Default constructor uses tesSUCCESS description
|
||||
{
|
||||
TER t;
|
||||
BEAST_EXPECT(t.code == tesSUCCESS);
|
||||
BEAST_EXPECT(t.reason == transHuman(TERRaw{tesSUCCESS}));
|
||||
}
|
||||
|
||||
// 4. Copy and move
|
||||
{
|
||||
TER t1 = {tecPATH_DRY, "reason 1"};
|
||||
TER t2 = t1;
|
||||
BEAST_EXPECT(t2.code == tecPATH_DRY);
|
||||
BEAST_EXPECT(t2.reason == "reason 1");
|
||||
|
||||
TER t3 = std::move(t1);
|
||||
BEAST_EXPECT(t3.code == tecPATH_DRY);
|
||||
BEAST_EXPECT(t3.reason == "reason 1");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
run() override
|
||||
{
|
||||
testTransResultInfo();
|
||||
testConversion();
|
||||
testComparison();
|
||||
testReason();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user