Source code

Revision control

Copy as Markdown

Other Tools

# rust_macros.py - Generate rust_macros bindings from IDL.
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
"""Generate rust bindings information for the IDL file specified"""
from xpidl import rust, xpidl
derive_method_tmpl = """\
Method {{
name: "{name}",
params: &[{params}],
ret: "{ret}",
}}"""
def attrAsMethodStruct(iface, m, getter):
params = [
f'Param {{ name: "{name}", ty: "{ty}" }}'
for name, ty in rust.attributeRawParamList(iface, m, getter)
]
return derive_method_tmpl.format(
name=rust.attributeNativeName(m, getter),
params=", ".join(params),
ret="::nserror::nsresult",
)
def methodAsMethodStruct(iface, m):
params = [
f'Param {{ name: "{name}", ty: "{ty}" }}'
for name, ty in rust.methodRawParamList(iface, m)
]
return derive_method_tmpl.format(
name=rust.methodNativeName(m),
params=", ".join(params),
ret=rust.methodReturnType(m),
)
derive_iface_tmpl = """\
Interface {{
name: "{name}",
base: {base},
sync: {sync},
methods: {methods},
}},
"""
def write_interface(iface, fd):
if iface.namemap is None:
raise Exception("Interface was not resolved.")
assert iface.base or (iface.name == "nsISupports")
base = f'Some("{iface.base}")' if iface.base is not None else "None"
try:
methods = ""
for member in iface.members:
if type(member) is xpidl.Attribute:
methods += f"/* {member.toIDL()} */\n"
methods += f"{attrAsMethodStruct(iface, member, True)},\n"
if not member.readonly:
methods += f"{attrAsMethodStruct(iface, member, False)},\n"
methods += "\n"
elif type(member) is xpidl.Method:
methods += f"/* {member.toIDL()} */\n"
methods += f"{methodAsMethodStruct(iface, member)},\n\n"
fd.write(
derive_iface_tmpl.format(
name=iface.name,
base=base,
sync="true" if iface.attributes.rust_sync else "false",
methods=f"Ok(&[\n{methods}])",
)
)
except xpidl.RustNoncompat as reason:
fd.write(
derive_iface_tmpl.format(
name=iface.name,
base=base,
sync="false",
methods=f'Err("{reason}")',
)
)
header = """\
//
// DO NOT EDIT. THIS FILE IS GENERATED FROM $SRCDIR/{relpath}
//
"""
def print_rust_macros_bindings(idl, fd, relpath):
fd = rust.AutoIndent(fd)
fd.write(header.format(relpath=relpath))
fd.write("{static D: &[Interface] = &[\n")
for p in idl.productions:
if p.kind == "interface":
write_interface(p, fd)
fd.write("]; D}\n")