This adds two related parts of the Rust bindings:
- QAPI code generator that creates Rust structs from the JSON
description. The structs are *not* ABI compatible with the
C ones, instead they use native Rust data types.
- QObject bindings and (de)serialization support, which can be used to
convert QObjects to and from QAPI structs.
Unfortunately Rust code is not able to use visitors, other than by
creating an intermediate QObject. This is because of the different
architecture of serde vs. QAPI visitors, and because visitor's
dual-purpose functions, where the same function is used by both input and
output visitors, rely heavily on the structs using the same representation
as the visitor arguments (for example NUL-terminated strings).
The serde format implementation was co-authored by me and Marc-André.
Marc-André did all the bug fixing and integration testing.
The main change from v2 is the introduction of two patches to
restrict a bit the QAPI language and embed some things that Rust's
type system enforces. I think both of them are sensible
restrictions in general:
- new patch "scripts/qapi: reject empty enums", because empty enums
cannot have any plausible meaning. Note that if all items are
conditional the enum is still allowed;
- new patch "scripts/qapi: enum with conditional first item must
be optional", to avoid giving different meanings to an all zero
struct; and also happening to catch the "all items are conditional"
case of the previous patch, ensuring that structs containing that
enum can be created.
Everything else is mostly cosmetic.
Paolo
v2->v3:
- QObject bindgen already done by rust/bindings/util-sys
- meson build rules are simpler due to util-sys vs util split
- comment adjustments for qobject/mod.rs
- preserve error from CStr::to_str() and CString::new()
- add de::Error implementation for qobject::error::Error
- new patch "scripts/qapi: reject empty enums"
- new patch "scripts/qapi: enum with conditional first item must be optional"
- add comment to commit message on why camer_to_upper()'s callers use
lstrip('_') for C
- new patch "allow passing multiple segments to mcgen" to improve
code formatting (fewer empty lines)
- add comment to commit message on why Rust for now is a separate backend
- rewrite to_camel_case(), changing 'foo-0123-bar' to 'Foo0123Bar' instead
of 'Foo_0123Bar'
- use blurb argument for QAPIGenRs constructor
Marc-André Lureau (6):
rust/qobject: add Display/Debug
scripts/qapi: add QAPISchemaIfCond.rsgen()
scripts/qapi: generate high-level Rust bindings
scripts/rustc_args: add --no-strict-cfg
rust/util: build QAPI types
rust/tests: QAPI integration tests
Paolo Bonzini (13):
rust/qobject: add basic bindings
subprojects: add serde
rust/qobject: add Serialize implementation
rust/qobject: add Serializer (to_qobject) implementation
rust/qobject: add Deserialize implementation
rust/qobject: add Deserializer (from_qobject) implementation
rust/qobject: add from/to JSON bindings for QObject
scripts/qapi: reject empty enums
scripts/qapi: enum with conditional first item must be optional
scripts/qapi: add QAPISchemaType.is_predefined
scripts/qapi: pull c_name and lstrip from camel_to_upper to caller
scripts/qapi: allow passing multiple segments to mcgen
scripts/qapi: add serde attributes
docs/devel/rust.rst | 1 +
meson.build | 4 +-
include/qobject/qobject.h | 5 +-
qapi/meson.build | 9 +
rust/Cargo.lock | 2 +
rust/Cargo.toml | 2 +
rust/meson.build | 4 +
rust/tests/meson.build | 21 +-
rust/tests/tests/integration.rs | 2 +
rust/tests/tests/qapi.rs | 444 +++++++++++++
rust/util/Cargo.toml | 2 +
rust/util/meson.build | 19 +-
rust/util/src/lib.rs | 4 +
rust/util/src/qobject/deserialize.rs | 134 ++++
rust/util/src/qobject/deserializer.rs | 371 +++++++++++
rust/util/src/qobject/error.rs | 58 ++
rust/util/src/qobject/mod.rs | 385 ++++++++++++
rust/util/src/qobject/serialize.rs | 57 ++
rust/util/src/qobject/serializer.rs | 585 ++++++++++++++++++
scripts/archive-source.sh | 3 +
scripts/make-release | 2 +-
scripts/qapi/backend.py | 25 +
scripts/qapi/common.py | 94 ++-
scripts/qapi/rs.py | 50 ++
scripts/qapi/rs_types.py | 393 ++++++++++++
scripts/qapi/schema.py | 86 ++-
scripts/rust/rustc_args.py | 16 +-
subprojects/.gitignore | 3 +
.../packagefiles/serde-1-rs/meson.build | 36 ++
.../packagefiles/serde-1.0.226-include.patch | 16 +
.../packagefiles/serde_core-1-rs/meson.build | 25 +
.../serde_core-1.0.226-include.patch | 15 +
.../serde_derive-1-rs/meson.build | 35 ++
.../serde_derive-1.0.226-include.patch | 11 +
subprojects/serde-1-rs.wrap | 11 +
subprojects/serde_core-1-rs.wrap | 11 +
subprojects/serde_derive-1-rs.wrap | 11 +
tests/qapi-schema/doc-good.json | 16 +-
tests/qapi-schema/doc-good.out | 12 +-
tests/qapi-schema/doc-good.txt | 8 +-
tests/qapi-schema/enum-empty.err | 2 +
tests/qapi-schema/enum-empty.json | 2 +
tests/qapi-schema/enum-empty.out | 0
tests/qapi-schema/enum-if-first-required.err | 2 +
tests/qapi-schema/enum-if-first-required.json | 6 +
tests/qapi-schema/enum-if-first-required.out | 0
tests/qapi-schema/meson.build | 2 +
tests/qapi-schema/qapi-schema-test.json | 3 -
tests/qapi-schema/qapi-schema-test.out | 1 -
tests/qapi-schema/union-empty.err | 4 +-
50 files changed, 2951 insertions(+), 59 deletions(-)
create mode 100644 rust/tests/tests/integration.rs
create mode 100644 rust/tests/tests/qapi.rs
create mode 100644 rust/util/src/qobject/deserialize.rs
create mode 100644 rust/util/src/qobject/deserializer.rs
create mode 100644 rust/util/src/qobject/error.rs
create mode 100644 rust/util/src/qobject/mod.rs
create mode 100644 rust/util/src/qobject/serialize.rs
create mode 100644 rust/util/src/qobject/serializer.rs
create mode 100644 scripts/qapi/rs.py
create mode 100644 scripts/qapi/rs_types.py
create mode 100644 subprojects/packagefiles/serde-1-rs/meson.build
create mode 100644 subprojects/packagefiles/serde-1.0.226-include.patch
create mode 100644 subprojects/packagefiles/serde_core-1-rs/meson.build
create mode 100644 subprojects/packagefiles/serde_core-1.0.226-include.patch
create mode 100644 subprojects/packagefiles/serde_derive-1-rs/meson.build
create mode 100644 subprojects/packagefiles/serde_derive-1.0.226-include.patch
create mode 100644 subprojects/serde-1-rs.wrap
create mode 100644 subprojects/serde_core-1-rs.wrap
create mode 100644 subprojects/serde_derive-1-rs.wrap
create mode 100644 tests/qapi-schema/enum-empty.err
create mode 100644 tests/qapi-schema/enum-empty.json
create mode 100644 tests/qapi-schema/enum-empty.out
create mode 100644 tests/qapi-schema/enum-if-first-required.err
create mode 100644 tests/qapi-schema/enum-if-first-required.json
create mode 100644 tests/qapi-schema/enum-if-first-required.out
--
2.54.0