Re: [PATCH 15/19] scripts/qapi: add serde attributes

Markus Armbruster <[email protected]>
Newsgroups org.nongnu.qemu-rust,org.nongnu.qemu-devel
Message-ID <[email protected]>
Paolo Bonzini <[email protected]> writes:

> From: Marc-André Lureau <[email protected]>
>
> Generate serde attributes to match the serialization format to QAPI's:
>
> - for enums, map Rust enum variants to original QAPI names
>
> - for structs, rejects JSON with extra fields and omit optional fields
>   (as opposed to serializing them as null)
>
> - for union variants:
>   - use tagged union format matching QAPI's discriminator,
>   - map variant names to original QAPI names
>   - flatten union data into parent struct
>
> - for alternates, use type-based discrimination
>
> Signed-off-by: Marc-André Lureau <[email protected]>
> Signed-off-by: Paolo Bonzini <[email protected]>

Again, quick look at the generated code first.

Diff since the previous patch, with comments inline:

  diff -rup ex/commit-450ce0c076/example-qapi-types.rs ex/commit-dc1aa3de44/example-qapi-types.rs
  --- ex/commit-450ce0c076/example-qapi-types.rs	2025-12-09 08:28:34.167519593 +0100
  +++ ex/commit-dc1aa3de44/example-qapi-types.rs	2025-12-09 08:30:13.913250024 +0100
  @@ -11,27 +11,38 @@
   // that *could* be Eq too.
   #![allow(clippy::derive_partial_eq_without_eq)]

  +use serde_derive::{Serialize, Deserialize};
  +
   use util::qobject::QObject;


   #[repr(u32)]
  -#[derive(Copy, Clone, Debug, PartialEq, common::TryInto)]
  +#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize,
  +         common::TryInto)]
   pub enum QType {

  +    #[serde(rename = "none")]
       NONE,

NONE is an error value.  It must not occur as type of a QObject (see
qobject_type()'s assertion).  It should never occur in serialization /
deserializion.  Is there a way to instruct serde accordingly?

Related: generated QType_lookup[] maps QTYPE_NONE to "none", because the
generator special case required to map it to NULL isn't worth the
bother.

  +    #[serde(rename = "qnull")]
       QNULL,

  +    #[serde(rename = "qnum")]
       QNUM,

  +    #[serde(rename = "qstring")]
       QSTRING,

  +    #[serde(rename = "qdict")]
       QDICT,

  +    #[serde(rename = "qlist")]
       QLIST,

  +    #[serde(rename = "qbool")]
       QBOOL,

  +    #[serde(rename = "_MAX")]
       _MAX,

This one must not occur, either.  Generated QType_lookup[] does not have
a value for it.

   }

  @@ -44,12 +55,16 @@ impl Default for QType {
   }


  -#[derive(Clone, Debug, PartialEq)]
  +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
  +#[serde(deny_unknown_fields)]
   pub struct UserDefOne {

  +    

Funny extra blank line, next patch will revert it.

       pub integer: i64,

  +    #[serde(skip_serializing_if = "Option::is_none")]
       pub string: Option<String>,

  +    #[serde(skip_serializing_if = "Option::is_none")]
       pub flag: Option<bool>,
   }
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.