#!/usr/bin/env python3 # Generates the `trezor_message_impl!` macro calls for the `src/messages/mod.rs` file. from os import path # Path to the `messages.proto` file PATH = path.abspath(path.join(__file__, "../../../../common/protob/messages.proto")) # Prefix of the enum variants PREFIX = "MessageType_" # Mapping of block name to feature name FEATURES = { # no features "Management": "default", "Bootloader": "default", "Crypto": "default", "Debug": "default", # "Bitcoin": "bitcoin", "Ethereum": "ethereum", # "Binance": "binance", "Cardano": "cardano", "EOS": "eos", "Monero": "monero", "NEM": "nem", "Ripple": "ripple", "Stellar": "stellar", "Tezos": "tezos", "WebAuthn": "webauthn", } MACRO = "trezor_message_impl" INDENT = " " def main(): blocks = get_blocks() features = {} defaults = [] for block, variants in blocks.items(): f = FEATURES.get(block) if not f or f == "default": defaults.extend(variants) else: vs = features.get(f) if vs: vs.extend(variants) else: features[f] = variants items = list(features.items()) items.sort() out = write_block(defaults) for feature, variants in items: if variants and feature: out += "\n" out += write_block(variants, feature) print(out.strip()) # Parse feature blocks based on comments in the `messages.proto` file def get_blocks() -> dict[str, list[str]]: blocks = {} current_block = "" with open(PATH, "r") as file: in_enum = False in_block_comment = False for line in file: line = line.strip() if "/*" in line: in_block_comment = True if "*/" in line: in_block_comment = False if in_block_comment: continue if line.startswith("enum MessageType {"): in_enum = True continue if in_enum: if line == "}": break if line.startswith("//"): comment = line.removeprefix("//").strip() if comment[0].isupper() and len(comment.split(" ")) == 1: current_block = comment blocks[current_block] = [] elif line.startswith(PREFIX): blocks[current_block].append(line.split(" ")[0]) return blocks # Writes a macro block def write_block(variants: list[str], feature: str = "") -> str: s = "" if feature: s += f'#[cfg(feature = "{feature}")]\n' s += f"{MACRO}! {{\n" for variant in variants: s += f"{INDENT}{variant.removeprefix(PREFIX)} => {variant},\n" s += "}\n" return s if __name__ == "__main__": main()