mirror of
https://github.com/logos-co/logos-protocol.git
synced 2026-08-27 12:01:15 +00:00
fix(json): keep nested bytes/ints tagged in qvariantToNlohmann containers (#23)
qvariantToNlohmann ran its canConvert<QJsonObject>/<QJsonArray> fallbacks BEFORE
the type-preserving QVariantList/QVariantMap recursion. A QVariantList/QVariantMap
also reports canConvert<QJson*>()==true, so a container was routed through QJson —
which has no byte type and degrades numerics to double. A nested QByteArray was
therefore flattened to a plain string, losing the canonical {"_bytes":...} tag.
Concretely this broke bstr method ARGUMENTS to cdylib (Rust) modules:
LogosProviderObject::callMethodStdBridge feeds each call arg through
qvariantToNlohmann, and a bstr arg arrives (over QtRO) as a QByteArray nested in
the QVariantList of call args. It was flattened to "hello", so the cdylib's
{"_bytes":...} decoder produced an empty Vec (e.g. echoBytes returned null). The
QtRO C++ path was unaffected (native QByteArray marshaling) and the plain-lp path
was already correct; only the container-through-QVariant leg dropped the tag.
Fix: move the container recursion (QStringList/QVariantList/QVariantMap) ahead of
the QJson fallbacks so nested elements recurse element-by-element (bytes stay
tagged, integers stay integers); only genuine QJson-typed variants reach the
fallbacks. Adds nested-bytes-in-list/map + bridge-shape regression tests.
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
1e96004711
commit
d5ba950313
+19
-11
@@ -60,17 +60,6 @@ nlohmann::json qvariantToNlohmann(const QVariant& v)
|
||||
return obj;
|
||||
}
|
||||
|
||||
if (v.canConvert<QJsonObject>()) {
|
||||
QJsonDocument doc(v.toJsonObject());
|
||||
try { return nlohmann::json::parse(doc.toJson(QJsonDocument::Compact).toStdString()); }
|
||||
catch (...) {}
|
||||
}
|
||||
if (v.canConvert<QJsonArray>()) {
|
||||
QJsonDocument doc(qvariant_cast<QJsonArray>(v));
|
||||
try { return nlohmann::json::parse(doc.toJson(QJsonDocument::Compact).toStdString()); }
|
||||
catch (...) {}
|
||||
}
|
||||
|
||||
// Integers stay integers: QJsonValue::fromVariant degrades every numeric
|
||||
// to double, which a strict consumer on the other side of the C ABI
|
||||
// (e.g. a generated dispatch reading an int param) must not see as 5.0.
|
||||
@@ -109,6 +98,25 @@ nlohmann::json qvariantToNlohmann(const QVariant& v)
|
||||
return obj;
|
||||
}
|
||||
|
||||
// Fallbacks for QVariants that are natively Qt JSON types (e.g. a module
|
||||
// handed back a QJsonObject/QJsonArray directly). These run AFTER the
|
||||
// container recursion above ON PURPOSE: a QVariantList/QVariantMap also
|
||||
// reports canConvert<QJsonArray/Object>(), and routing it through QJson here
|
||||
// would flatten a nested QByteArray to a plain string (QJson has no byte
|
||||
// type) and degrade nested numerics to double — the exact losses the
|
||||
// recursion prevents. So containers must be handled first; only genuine
|
||||
// QJson-typed variants reach this point.
|
||||
if (v.canConvert<QJsonObject>()) {
|
||||
QJsonDocument doc(v.toJsonObject());
|
||||
try { return nlohmann::json::parse(doc.toJson(QJsonDocument::Compact).toStdString()); }
|
||||
catch (...) {}
|
||||
}
|
||||
if (v.canConvert<QJsonArray>()) {
|
||||
QJsonDocument doc(qvariant_cast<QJsonArray>(v));
|
||||
try { return nlohmann::json::parse(doc.toJson(QJsonDocument::Compact).toStdString()); }
|
||||
catch (...) {}
|
||||
}
|
||||
|
||||
QJsonValue jv = QJsonValue::fromVariant(v);
|
||||
if (jv.isString()) return jv.toString().toStdString();
|
||||
if (jv.isBool()) return jv.toBool();
|
||||
|
||||
Reference in New Issue
Block a user