[PATCH v2 09/16] scripts/qapi: add QAPISchemaIfCond.rsgen()

Paolo Bonzini
2026-01-08T13:11:23Z

From: Marc-André Lureau <marcandre.lureau@redhat.com>

Generate Rust #[cfg(...)] guards from QAPI 'if' conditions; it
turns out that they are very similar, with both of them using
not/any/all, so just walk the tree.

The next commit will put it to use.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Link: https://lore.kernel.org/r/20210907121943.3498701-15-marcandre.lureau@redhat.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
scripts/qapi/common.py | 19 +++++++++++++++++++
scripts/qapi/schema.py | 4 ++++
2 files changed, 23 insertions(+)

diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py
index d7c8aa3365c..14d5dd259c4 100644
--- a/scripts/qapi/common.py
+++ b/scripts/qapi/common.py
@@ -199,6 +199,25 @@ def guardend(name: str) -> str:
name=c_fname(name).upper())

+def rsgen_ifcond(ifcond: Optional[Union[str, Dict[str, Any]]]) -> str:
+
+ def cfg(ifcond: Union[str, Dict[str, Any]]) -> str:
+ if isinstance(ifcond, str):
+ return ifcond
+ assert isinstance(ifcond, dict) and len(ifcond) == 1
+ if 'not' in ifcond:
+ oper = 'not'
+ arg = cfg(ifcond['not'])
+ else:
+ oper, operands = next(iter(ifcond.items()))
+ arg = ', '.join([cfg(c) for c in operands])
+ return f'{oper}({arg})'
+
+ if not ifcond:
+ return ''
+ return '#[cfg(%s)]' % cfg(ifcond)
+
+
def gen_ifcond(ifcond: Optional[Union[str, Dict[str, Any]]],
cond_fmt: str, not_fmt: str,
all_operator: str, any_operator: str) -> str:
diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py
index 8d88b40de2e..848a7401251 100644
--- a/scripts/qapi/schema.py
+++ b/scripts/qapi/schema.py
@@ -37,6 +37,7 @@
docgen_ifcond,
gen_endif,
gen_if,
+ rsgen_ifcond,
)
from .error import QAPIError, QAPISemError, QAPISourceError
from .expr import check_exprs
@@ -63,6 +64,9 @@ def gen_endif(self) -> str:
def docgen(self) -> str:
return docgen_ifcond(self.ifcond)

+ def rsgen(self) -> str:
+ return rsgen_ifcond(self.ifcond)
+
def is_present(self) -> bool:
return bool(self.ifcond)

--
2.52.0