Re: [PATCH 14/19] scripts/qapi: generate high-level Rust bindings
Paolo Bonzini <[email protected]>
| Newsgroups | org.nongnu.qemu-rust,org.nongnu.qemu-devel |
|---|---|
| Message-ID | <[email protected]> |
On 12/17/25 14:32, Markus Armbruster wrote:
> This is like common.c_name(). Differences:
>
> 1. Funny input characters
>
> c_name() returns a valid C identifier for any non-empty input.
>
> rs_name() requires its argument to contain only characters valid in
> Rust identifiers plus '.' and '-'.
>
> I think we better avoid this difference.
Done.
> 3. Input starting with a digit
>
> c_name() treats them just like protected identifiers, i.e. prefix
> with 'q_' when @protect.
>
> rs_name() prefixes with '_'. Is this a good idea? Hmm... "The Rust
> Reference:
>
> Note
>
> Identifiers starting with an underscore are typically used to
> indicate an identifier that is intentionally unused, and will
> silence the unused warning in rustc.
>
> https://doc.rust-lang.org/reference/identifiers.html
In this case it doesn't really matter: public items (such as QAPI enum
entries, or struct fields) do not raise the unused warning anyway.
> rs_name() prefixes always, not just when @protect. Is this a good
> idea? Remember, @protect is typically false when the output is used
> as part of an identifier. Or do we use it differently for Rust?
Removed @protect, as it was unused for Rust. Makes sense, because Rust
uses Enum::Ident instead of ENUM_IDENT.
> 4. Name clash avoidance
>
> c_name() treats names that are prone to clash as protected,
> i.e. prefix 'q_' unless @protect.
>
> rs_name() prefixes 'Qapi' instead. Why?
Because Rust tools are a bit more fussy about the shape of the
identifiers; in particular they want types and enum names to start with
an uppercase letter and use camel case. Using 'q_' as the prefix makes
them complain.
Fortunately this is limited to String, which has very limited uses... I
don't remember why String exists, probably strList wasn't a thing yet?
>> +
>> +
>> +def rs_type(c_type: str,
>> + qapi_ns: str = 'qapi::',
>> + optional: bool = False,
>> + box: bool = False) -> str:
>> + (is_pointer, _, is_list, c_type) = rs_ctype_parse(c_type)
>> + to_rs = {
>> + 'QNull': '()',
>> + 'QObject': 'QObject',
>> + 'any': 'QObject',
>> + 'bool': 'bool',
>> + 'char': 'i8',
>> + 'double': 'f64',
>> + 'int': 'i64',
>> + 'int16': 'i16',
>> + 'int16_t': 'i16',
>> + 'int32': 'i32',
>> + 'int32_t': 'i32',
>> + 'int64': 'i64',
>> + 'int64_t': 'i64',
>> + 'int8': 'i8',
>> + 'int8_t': 'i8',
>> + 'number': 'f64',
>> + 'size': 'u64',
>> + 'str': 'String',
>> + 'uint16': 'u16',
>> + 'uint16_t': 'u16',
>> + 'uint32': 'u32',
>> + 'uint32_t': 'u32',
>> + 'uint64': 'u64',
>> + 'uint64_t': 'u64',
>> + 'uint8': 'u8',
>> + 'uint8_t': 'u8',
>> + 'String': 'QapiString',
>> + }
>
> The argument name @c_type suggests it is a C type, but this map contains
> a mix of C types, QAPI built-in types, and even a user-defined QAPI type
> (String). How come?
>
> Why do we even have to map from C type to Rust type? Why can't we map
> from QAPI type to Rust type, like we map from QAPI type to C type?
I'll look into it.
All other comments addressed, thanks for the review!
Paolo