On 12/5/25 11:04, Markus Armbruster wrote:
Paolo Bonzini <[email protected]> writes:
These are used by tests. However it could even be an idea to use
serde_json + transcoding and get rid of the C version...
Tell me more!
QEMU's JSON parser produces a QObject. To obtain the same effect, we
can take JSON-string-to-serde deserialization (implemented by
serde_json) and attach it to serde-to-QObject serialization (the thing
in patch 5). That results in a JSON-string-to-QObject function.
Doing it in the other direction (QObject deserializer + JSON-string
serializer) produces a QObject-to-JSON-string function.
For a little more information see https://serde.rs/transcode.html.
Note however that there is no support for push parsing, therefore this
would not replace the balanced-parentheses machinery in
qobject/json-streamer.c, and therefore QMP would still need a minimal lexer.
Grr... I just remembered about interpolation :/ so no, we still need a
parser for libqmp.c.
Paolo
Co-authored-by: Marc-André Lureau <[email protected]>
Signed-off-by: Marc-André Lureau <[email protected]>
Signed-off-by: Paolo Bonzini <[email protected]>
---
rust/util/wrapper.h | 1 +
rust/util/src/qobject/mod.rs | 17 +++++++++++++++++
2 files changed, 18 insertions(+)
diff --git a/rust/util/wrapper.h b/rust/util/wrapper.h
index 0907dd59142..c88820a5e5b 100644
--- a/rust/util/wrapper.h
+++ b/rust/util/wrapper.h
@@ -37,3 +37,4 @@ typedef enum memory_order {
#include "qobject/qobject.h"
#include "qobject/qlist.h"
#include "qobject/qdict.h"
+#include "qobject/qjson.h"
diff --git a/rust/util/src/qobject/mod.rs b/rust/util/src/qobject/mod.rs
index e896aba5f3a..292a3c9c238 100644
--- a/rust/util/src/qobject/mod.rs
+++ b/rust/util/src/qobject/mod.rs
@@ -23,6 +23,7 @@
use common::assert_field_type;
pub use deserializer::from_qobject;
pub use error::{Error, Result};
+use foreign::prelude::*;
pub use serializer::to_qobject;
use crate::bindings;
@@ -111,6 +112,22 @@ fn refcnt(&self) -> &AtomicUsize {
let qobj = self.0.get();
unsafe { AtomicUsize::from_ptr(addr_of_mut!((*qobj).base.refcnt)) }
}
+
+ pub fn to_json(&self) -> String {
+ let qobj = self.0.get();
+ unsafe {
+ let json = bindings::qobject_to_json(qobj);
+ glib_sys::g_string_free(json, glib_sys::GFALSE).into_native()
+ }
+ }
+
+ pub fn from_json(json: &str) -> std::result::Result<Self, crate::Error> {
+ let c_json = std::ffi::CString::new(json)?;
+ unsafe {
+ crate::Error::with_errp(|errp|
bindings::qobject_from_json(c_json.as_ptr(), errp))
+ .map(|qobj| QObject::from_raw(qobj))
+ }
+ }
}
impl From<()> for QObject {