Re: [PATCH 11/19] rust/qobject: add from/to JSON bindings for QObject
Paolo Bonzini <[email protected]>
| Newsgroups | org.nongnu.qemu-rust,org.nongnu.qemu-devel |
|---|---|
| Message-ID | <[email protected]> |
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 { > > >