Full Code of evanw/miniffi for AI

main 6bb24fb5d5e3 cached
815 files
2.4 MB
673.5k tokens
5666 symbols
1 requests
Download .txt
Showing preview only (2,679K chars total). Download the full file or copy to clipboard to get everything.
Repository: evanw/miniffi
Branch: main
Commit: 6bb24fb5d5e3
Files: 815
Total size: 2.4 MB

Directory structure:
gitextract_elwbkvg6/

├── Cargo.toml
├── LICENSE.md
├── README.md
└── src/
    ├── ast.rs
    ├── cpp.rs
    ├── lib.rs
    ├── rust.rs
    ├── scan.rs
    ├── swift.rs
    ├── tests/
    │   ├── cases/
    │   │   ├── demo_app.rs
    │   │   ├── demo_const.rs
    │   │   ├── demo_derive_eq.rs
    │   │   ├── demo_enum.rs
    │   │   ├── demo_keyword.rs
    │   │   ├── demo_order.rs
    │   │   ├── demo_trait.rs
    │   │   ├── fn_basic.rs
    │   │   ├── fn_basic_void.rs
    │   │   ├── fn_box_in.rs
    │   │   ├── fn_box_out.rs
    │   │   ├── fn_combo_in.rs
    │   │   ├── fn_combo_out.rs
    │   │   ├── fn_enum_in.rs
    │   │   ├── fn_enum_out.rs
    │   │   ├── fn_nested_in.rs
    │   │   ├── fn_nested_out.rs
    │   │   ├── fn_option_in.rs
    │   │   ├── fn_option_out.rs
    │   │   ├── fn_payload_in.rs
    │   │   ├── fn_payload_out.rs
    │   │   ├── fn_string.rs
    │   │   ├── fn_struct_in.rs
    │   │   ├── fn_struct_out.rs
    │   │   ├── fn_tuple_in.rs
    │   │   ├── fn_tuple_out.rs
    │   │   ├── fn_vec_in.rs
    │   │   ├── fn_vec_out.rs
    │   │   ├── mod.rs
    │   │   ├── trait_enum.rs
    │   │   ├── trait_export.rs
    │   │   ├── trait_export_import.rs
    │   │   ├── trait_export_nested.rs
    │   │   ├── trait_import.rs
    │   │   ├── trait_import_export.rs
    │   │   ├── trait_import_nested.rs
    │   │   ├── trait_import_struct_in.rs
    │   │   ├── trait_import_tuple_in.rs
    │   │   └── trait_string.rs
    │   ├── cpp.rs
    │   ├── mod.rs
    │   ├── snapshots/
    │   │   ├── cpp_demo_app_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_demo_app_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_demo_const_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_demo_const_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_demo_derive_eq_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_demo_derive_eq_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_demo_enum_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_demo_enum_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_demo_keyword_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_demo_keyword_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_demo_order_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_demo_order_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_demo_trait_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_demo_trait_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_basic_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_basic_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_basic_void_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_basic_void_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_box_in_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_box_in_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_box_out_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_box_out_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_combo_in_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_combo_in_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_combo_out_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_combo_out_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_enum_in_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_enum_in_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_enum_out_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_enum_out_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_nested_in_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_nested_in_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_nested_out_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_nested_out_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_option_in_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_option_in_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_option_out_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_option_out_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_payload_in_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_payload_in_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_payload_out_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_payload_out_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_string_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_string_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_struct_in_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_struct_in_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_struct_out_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_struct_out_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_tuple_in_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_tuple_in_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_tuple_out_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_tuple_out_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_vec_in_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_vec_in_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_vec_out_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_vec_out_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_trait_enum_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_trait_enum_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_trait_export_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_trait_export_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_trait_export_import_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_trait_export_import_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_trait_export_nested_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_trait_export_nested_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_trait_import_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_trait_import_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_trait_import_export_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_trait_import_export_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_trait_import_nested_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_trait_import_nested_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_trait_import_struct_in_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_trait_import_struct_in_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_trait_import_tuple_in_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_trait_import_tuple_in_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_trait_string_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_trait_string_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── swift_demo_app_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_demo_app_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_demo_const_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_demo_const_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_demo_derive_eq_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_demo_derive_eq_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_demo_enum_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_demo_enum_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_demo_keyword_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_demo_keyword_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_demo_order_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_demo_order_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_demo_trait_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_demo_trait_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_basic_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_basic_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_basic_void_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_basic_void_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_box_in_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_box_in_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_box_out_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_box_out_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_combo_in_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_combo_in_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_combo_out_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_combo_out_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_enum_in_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_enum_in_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_enum_out_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_enum_out_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_nested_in_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_nested_in_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_nested_out_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_nested_out_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_option_in_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_option_in_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_option_out_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_option_out_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_payload_in_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_payload_in_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_payload_out_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_payload_out_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_string_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_string_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_struct_in_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_struct_in_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_struct_out_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_struct_out_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_tuple_in_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_tuple_in_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_tuple_out_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_tuple_out_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_vec_in_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_vec_in_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_vec_out_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_vec_out_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_trait_enum_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_trait_enum_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_trait_export_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_trait_export_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_trait_export_import_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_trait_export_import_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_trait_export_nested_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_trait_export_nested_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_trait_import_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_trait_import_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_trait_import_export_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_trait_import_export_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_trait_import_nested_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_trait_import_nested_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_trait_import_struct_in_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_trait_import_struct_in_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_trait_import_tuple_in_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_trait_import_tuple_in_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_trait_string_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_trait_string_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_demo_app_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_demo_app_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_demo_const_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_demo_const_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_demo_derive_eq_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_demo_derive_eq_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_demo_enum_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_demo_enum_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_demo_keyword_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_demo_keyword_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_demo_order_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_demo_order_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_demo_trait_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_demo_trait_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_basic_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_basic_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_basic_void_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_basic_void_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_box_in_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_box_in_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_box_out_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_box_out_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_combo_in_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_combo_in_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_combo_out_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_combo_out_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_enum_in_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_enum_in_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_enum_out_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_enum_out_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_nested_in_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_nested_in_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_nested_out_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_nested_out_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_option_in_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_option_in_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_option_out_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_option_out_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_payload_in_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_payload_in_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_payload_out_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_payload_out_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_string_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_string_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_struct_in_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_struct_in_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_struct_out_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_struct_out_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_tuple_in_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_tuple_in_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_tuple_out_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_tuple_out_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_vec_in_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_vec_in_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_vec_out_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_vec_out_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_trait_enum_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_trait_enum_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_trait_export_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_trait_export_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_trait_export_import_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_trait_export_import_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_trait_export_nested_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_trait_export_nested_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_trait_import_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_trait_import_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_trait_import_export_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_trait_import_export_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_trait_import_nested_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_trait_import_nested_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_trait_import_struct_in_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_trait_import_struct_in_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_trait_import_tuple_in_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_trait_import_tuple_in_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_trait_string_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   └── wasm_trait_string_2024/
    │   │       ├── ffi.d.mts
    │   │       ├── ffi.mjs
    │   │       ├── ffi.mts
    │   │       └── miniffi.rs
    │   ├── swift.rs
    │   ├── warnings.rs
    │   └── wasm.rs
    ├── util.rs
    └── wasm.rs

================================================
FILE CONTENTS
================================================

================================================
FILE: Cargo.toml
================================================
[package]
name = "miniffi"
version = "0.1.0"
edition = "2021"
license = "MIT"
repository = "https://github.com/evanw/miniffi"
description = "A simple but opinionated FFI system"
exclude = ["src/tests"]

[dependencies]
proc-macro2 = { version = "1.0.60", features = ["span-locations"] }
syn = { version = "2.0.0", default-features = false, features = ["full", "parsing", "printing"] }


================================================
FILE: LICENSE.md
================================================
Copyright 2025 Evan Wallace

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


================================================
FILE: README.md
================================================
# miniffi

> [!WARNING]
> This project is on its first release. I'm still trying out the idea. It has
> not been used in production.

This is a simple but opinionated FFI system for Rust. It allows you to call Rust code from other
languages, and vice versa. Some design principles:

- Intended for writing platform-agnostic Rust with platform-specific details in the host language
- FFI support is split into data (structs passed by copy) and code (traits passed by reference)
- Rather than have a separate schema language, the public API in your `lib.rs` is your schema
- The generated binding code is compact, dependency-free, and straightforward to integrate with

## Supported Features

- Primitive types (`bool`, `i32`, `f64`, `String`, etc.)
- Tuples
- Structs
- Enums
- Top-level constants
- Top-level functions
- Traits (must be either `Box<dyn T>` or `Rc<dyn T>`)
- `Vec<T>`
- `Option<T>`
- `Box<T>`

## Available Targets

- JavaScript/TypeScript (WASM)
- Swift
- C++

## Example

After setting everything up, using miniffi looks something like this. The
following example Rust code (in `lib.rs`) demonstrates passing code and
data back and forth between Rust and the host language:

```rs
pub enum Level {
    Warning,
    Error,
}

pub trait Logger {
    fn log(&self, level: Level, text: &str);
}

pub trait Demo {
    fn run(&self, logger: Box<dyn Logger>);
}

pub fn get_demo() -> Box<dyn Demo> {
    struct DemoImpl;
    impl Demo for DemoImpl {
        fn run(&self, logger: Box<dyn Logger>) {
            logger.log(Level::Warning, "example");
        }
    }
    Box::new(DemoImpl)
}

// This includes the binding code generated by miniffi
include!(concat!(env!("OUT_DIR"), "/miniffi.rs"));
```

Unlike other FFI systems, there are no annotations required to expose something
from `lib.rs` to the host language other than using `pub` to mark things public.
The miniffi build script parses `lib.rs`, extracts the supported parts of the
public API, and generates FFI binding code both for Rust (the `miniffi.rs` file
referenced above) and for the host language. Calling that example Rust code
might look like this:

In JavaScript/TypeScript:

```js
import * as rust from "./miniffi.js"
import fs from "fs"

await rust.instantiate(fs.readFileSync(
    "./target/wasm32-unknown-unknown/debug/example.wasm"))

rust.get_demo().run({
    log(level, text) {
        if (level === rust.Level.Error)
            console.error("ERROR:", text)
        else if (level === rust.Level.Warning)
            console.warn("WARNING:", text)
    }
})
```

In Swift:

```swift
class LoggerImpl : Logger {
    func log(_ level: Level, _ text: String) {
        if level == .Error {
            print("ERROR:", text)
        } else if level == .Warning {
            print("WARNING:", text)
        }
    }
}

get_demo().run(LoggerImpl())
```

In C++:

```c++
#include <iostream>
#include "ffi.h"

struct LoggerImpl : rust::Logger {
    void log(rust::Level level, std::string text) {
        if (level == rust::Level::Error)
            std::cout << "ERROR: " << text << std::endl;
        else if (level == rust::Level::Warning)
            std::cout << "WARNING: " << text << std::endl;
    }
};

int main() {
    rust::get_demo()->run(std::make_unique<LoggerImpl>());
    return 0;
}
```

More information about how to use miniffi can be found in the [documentation](https://docs.rs/miniffi/latest/miniffi/).

## Similar Projects

These projects are much further along, and you may want to use them instead:

- [UniFFI](https://github.com/mozilla/uniffi-rs)
- [Diplomat](https://github.com/rust-diplomat/diplomat)
- [Interoptopus](https://github.com/ralfbiedert/interoptopus)


================================================
FILE: src/ast.rs
================================================
use super::*;
use std::collections::HashSet;
use std::fmt::Write;

pub struct AST {
    pub structs: Vec<RustStruct>,
    pub enums: Vec<RustEnum>,
    pub traits: Vec<RustTrait>,
    pub consts: Vec<RustConst>,
    pub fns: Vec<RustFn>,
}

impl AST {
    pub fn rename_keywords(&mut self, keywords: &[&str]) {
        let keywords: HashSet<_> = keywords.iter().map(|x| *x).collect();
        let mut names = NameSet::default();
        for k in &keywords {
            names.add(k.to_string());
        }

        // Avoid the "_" symbol in Rust
        names.add("_".to_string());

        let rename_keywords_in_fn = move |f: &mut RustFn| {
            // Avoid cloning the set in the common case
            if !f
                .args
                .iter()
                .chain(f.returns.iter())
                .any(|x| names.contains(x.name.as_str()))
            {
                return;
            }

            // Rename all relevant local identifiers
            let mut names = names.clone();
            for arg in &mut f.args {
                arg.name = names.create(&arg.name);
            }
            if let Some(ret) = &mut f.returns {
                ret.name = names.create(&ret.name);
            }
        };

        for f in &mut self.fns {
            rename_keywords_in_fn(f);
        }

        for t in &mut self.traits {
            for f in &mut t.fns {
                rename_keywords_in_fn(f);
            }
        }
    }
}

pub struct RustStruct {
    pub name: String,
    pub fields: Vec<RustField>,
    pub derives_partial_eq: bool,
}

pub struct RustEnum {
    pub name: String,
    pub variants: Vec<RustVariant>,
    pub derives_partial_eq: bool,
}

impl RustEnum {
    pub fn has_fields(&self) -> bool {
        self.variants.iter().any(|v| !v.fields.is_empty())
    }
}

pub struct RustVariant {
    pub name: String,
    pub discriminant: i32,
    pub fields: Vec<RustField>,
}

pub struct RustTrait {
    pub name: String,
    pub fns: Vec<RustFn>,
}

#[derive(Clone)]
pub struct RustField {
    pub name: String,
    pub ty: RustType,
}

pub struct RustConst {
    pub name: String,
    pub ty: RustType,
    pub val: RustVal,
}

pub struct RustFn {
    pub name: String,
    pub args: Vec<RustArg>,
    pub returns: Option<RustArg>,
}

#[derive(Clone)]
pub struct RustArg {
    pub name: String,
    pub ty: RustType,
}

#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub enum RustPtr {
    Box,
    Rc,
}

impl RustPtr {
    pub fn path(&self) -> &'static str {
        match self {
            RustPtr::Box => "Box",
            RustPtr::Rc => "std::rc::Rc",
        }
    }
}

#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub enum RustType {
    Pair {
        rust: Box<RustType>,
        other: Box<RustType>,
    },
    Verbatim(String),
    Bool,

    U8,
    U16,
    U32,
    Usize,
    U64,

    I8,
    I16,
    I32,
    Isize,
    I64,

    F32,
    F64,

    RefStr,
    OwnStr,

    Struct(usize),
    Enum(usize),
    DynTrait(usize),
    Ptr(RustPtr, Box<RustType>),
    Vector(Box<RustType>),
    Tuple(Vec<RustType>),
    Optional(Box<RustType>),

    ForeignHandle,
}

#[derive(Clone, Debug, PartialEq)]
pub enum RustVal {
    Bool(bool),

    U8(u8),
    U16(u16),
    U32(u32),
    U64(u64),

    I8(i8),
    I16(i16),
    I32(i32),
    I64(i64),

    F32(f32),
    F64(f64),

    Str(String),
}

pub fn append_type_name_hint(out: &mut String, ast: &AST, ty: &RustType) {
    use RustType::*;
    match ty {
        Pair { rust, .. } => append_type_name_hint(out, ast, rust),
        Verbatim(text) => out.push_str(text),
        Bool => out.push_str("bool"),

        U8 => out.push_str("u8"),
        U16 => out.push_str("u16"),
        U32 => out.push_str("u32"),
        Usize => out.push_str("usize"),
        U64 => out.push_str("u64"),

        I8 => out.push_str("i8"),
        I16 => out.push_str("i16"),
        I32 => out.push_str("i32"),
        Isize => out.push_str("isize"),
        I64 => out.push_str("i64"),

        F32 => out.push_str("f32"),
        F64 => out.push_str("f64"),

        RefStr => out.push_str("str"),
        OwnStr => out.push_str("string"),

        Struct(index) => out.push_str(&ast.structs[*index].name),
        Enum(index) => out.push_str(&ast.enums[*index].name),

        DynTrait(index) => {
            out.push_str("dyn_");
            out.push_str(&ast.traits[*index].name);
        }

        Ptr(kind, inner) => {
            out.push_str(match kind {
                RustPtr::Box => "box_",
                RustPtr::Rc => "rc_",
            });
            append_type_name_hint(out, ast, &inner);
        }

        Vector(inner) => {
            out.push_str("vec_");
            append_type_name_hint(out, ast, &inner);
        }

        Tuple(types) => {
            for (i, ty) in types.iter().enumerate() {
                if i > 0 {
                    out.push_str("_");
                }
                append_type_name_hint(out, ast, ty);
            }
        }

        Optional(inner) => {
            out.push_str("option_");
            append_type_name_hint(out, ast, &inner);
        }

        ForeignHandle => out.push_str("ptr"),
    }
}

pub fn append_type_name_hints(out: &mut String, ast: &AST, types: &[RustType]) {
    let mut i = 0;
    while i < types.len() {
        if i > 0 {
            out.push('_');
        }
        let ty = &types[i];
        let mut counter = 1;
        i += 1;
        while i < types.len() && ty == &types[i] {
            counter += 1;
            i += 1;
        }
        if counter > 1 {
            _ = write!(out, "{counter}_");
        }
        append_type_name_hint(out, ast, ty);
    }
}


================================================
FILE: src/cpp.rs
================================================
use super::*;
use std::borrow::Cow;
use std::collections::{HashMap, HashSet};
use std::hash::Hash;
use std::rc::Rc;

/// Use this target when the host language is C++.
///
/// This needs to generate a source file (`.cpp`, `.cc`, etc.) and a header
/// file (`.hpp`, `.h`, etc.). By default, the files will be named
/// `miniffi.cpp` and `miniffi.h` and will be written to the directory
/// containing your `Cargo.toml` file. You can customize these paths before
/// calling [`build`](Target::build):
///
/// ```no_run
/// use miniffi::*;
///
/// fn main() {
///     CppTarget::new()
///         .write_source_to("../app/rust.cpp")
///         .write_header_to("../app/rust.h")
///         .build();
/// }
/// ```
///
/// Generated bindings for calling your Rust code from C++ will be placed in
/// the `rust` namespace. For example, if your `src/lib.rs` looks like this:
///
/// ```no_run
/// pub fn add(left: u64, right: u64) -> u64 {
///     left + right
/// }
///
/// # macro_rules! env { ($a:expr) => { $a } }
/// # macro_rules! include { ($a:expr) => { $a } }
/// include!(concat!(env!("OUT_DIR"), "/miniffi.rs"));
/// ```
///
/// You can call that from C++ like this:
///
/// ```c++
/// #include <iostream>
/// #include "miniffi.h"
///
/// int main() {
///     std::cout << "1 + 2 = " << rust::add(1, 2) << std::endl;
///     return 0;
/// }
/// ```
///
/// The generated code tries to map Rust types into the corresponding types
/// from the C++ standard template library:
///
/// | Rust type   | C++ type                             |
/// |-------------|--------------------------------------|
/// | `String`    | `std::string`                        |
/// | `Vec<T>`    | `std::vector<T>`                     |
/// | `(A, B)`    | `std::tuple<A, B>` *(since C++11)*   |
/// | `Box<T>`    | `std::unique_ptr<T>` *(since C++11)* |
/// | `Rc<T>`     | `std::shared_ptr<T>` *(since C++11)* |
/// | `Option<T>` | `std::optional<T>` *(since C++17)*   |
///
/// Enums without fields are turned into a C++ enum struct:
///
/// <table>
/// <tr><th>Rust</th><th>C++</th></tr>
/// <tr><td valign=top>
///
/// ```
/// // Exported enum in Rust
/// pub enum Color {
///     Window,
///     Text,
/// }
///
/// // Example usage
/// let color = Color::Text;
/// let hex = match color {
///     Color::Window => 0x353535,
///     Color::Text => 0xD2991D,
/// };
/// ```
///
/// </td><td valign=top>
///
/// ```c++
/// // Generated enum in C++
/// enum struct Color : int32_t {
///     Window = 0,
///     Text = 1,
/// };
///
/// // Example usage
/// auto color = Color::Text;
/// int hex;
/// if (color == Color::Window)
///     hex = 0x353535;
/// else if (color == Color::Text)
///     hex = 0xD2991D;
/// else
///     std::abort();
/// ```
///
/// </td></tr>
/// </table>
///
/// Enums with fields use `std::variant` from C++17:
///
/// <table>
/// <tr><th>Rust</th><th>C++</th></tr>
/// <tr><td valign=top>
///
/// ```
/// // Exported enum in Rust
/// pub enum Color {
///     Window,
///     Text,
///     RGB(u8, u8, u8),
/// }
///
/// // Example usage
/// let color = Color::RGB(255, 0, 0);
/// let hex = match color {
///     Color::Window => 0x353535,
///     Color::Text => 0xD2991D,
///     Color::RGB(r, g, b) =>
///         u32::from_le_bytes([b, g, r, 0]),
/// };
/// ```
///
/// </td><td valign=top>
///
/// ```c++
/// // Generated enum in C++ (approximately)
/// struct Color : std::variant<...> {
///     struct Window {};
///     struct Text {};
///     struct RGB { uint8_t _0, _1, _2; };
///     template <typename T> bool is();
///     template <typename T> T* as();
/// };
///
/// // Example usage
/// Color color{ Color::RGB{ 255, 0, 0 } };
/// int hex;
/// if (color.is<Color::Window>())
///     hex = 0x353535;
/// else if (color.is<Color::Text>())
///     hex = 0xD2991D;
/// else if (auto x = color.as<Color::RGB>())
///     hex = (x->_0 << 16) | (x->_1 << 8) | x->_2;
/// else
///     std::abort();
/// ```
///
/// </td></tr>
/// </table>
///
/// ## Using the command line
///
/// If you are using C++ from the command line, then you can call Rust from
/// C++ by compiling the generated `.cpp` file and linking that along with the
/// compiled Rust code to the rest of your C++. For example:
///
/// ```text
/// # Build the Rust code
/// cargo rustc --crate-type=staticlib
///
/// # Build the C++ code
/// c++ -std=c++17 main.cpp miniffi.cpp ./target/debug/libexample.a
/// ```
pub struct CppTarget {
    common_options: CommonOptions,
    namespace: String,
    source_path: PathBuf,
    header_path: PathBuf,
}

impl CppTarget {
    pub fn new() -> CppTarget {
        CppTarget {
            common_options: CommonOptions::default(),
            namespace: "rust".to_string(),
            source_path: "miniffi.cpp".into(),
            header_path: "miniffi.h".into(),
        }
    }

    pub fn write_source_to<T: Into<PathBuf>>(mut self, path: T) -> Self {
        self.source_path = path.into();
        self
    }

    pub fn write_header_to<T: Into<PathBuf>>(mut self, path: T) -> Self {
        self.header_path = path.into();
        self
    }
}

pub const CPP_KEYWORDS: &[&str] = &[
    "alignas",
    "alignof",
    "and",
    "and_eq",
    "asm",
    "atomic_cancel",
    "atomic_commit",
    "atomic_noexcept",
    "auto",
    "bitand",
    "bitor",
    "bool",
    "break",
    "case",
    "catch",
    "char",
    "char8_t",
    "char16_t",
    "char32_t",
    "class",
    "compl",
    "concept",
    "const",
    "consteval",
    "constexpr",
    "constinit",
    "const_cast",
    "continue",
    "contract_assert",
    "co_await",
    "co_return",
    "co_yield",
    "decltype",
    "default",
    "delete",
    "do",
    "double",
    "dynamic_cast",
    "else",
    "enum",
    "explicit",
    "export",
    "extern",
    "false",
    "float",
    "for",
    "friend",
    "goto",
    "if",
    "inline",
    "int",
    "long",
    "mutable",
    "namespace",
    "new",
    "noexcept",
    "not",
    "not_eq",
    "nullptr",
    "operator",
    "or",
    "or_eq",
    "private",
    "protected",
    "public",
    "reflexpr",
    "register",
    "reinterpret_cast",
    "requires",
    "return",
    "short",
    "signed",
    "sizeof",
    "static",
    "static_assert",
    "static_cast",
    "struct",
    "switch",
    "synchronized",
    "template",
    "this",
    "thread_local",
    "throw",
    "true",
    "try",
    "typedef",
    "typeid",
    "typename",
    "union",
    "unsigned",
    "using",
    "virtual",
    "void",
    "volatile",
    "wchar_t",
    "while",
    "xor",
    "xor_eq",
];

#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
enum HeaderGroup {
    Include,
    ForwardDecl,
    Other,
    Constants,
}

#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
enum SourceGroup {
    Include,
    MultiRet,
    ExternCDecl,
    ExternCImpl,
    Anonymous,
    Other,
}

impl Compile for CppTarget {
    fn common_options(&mut self) -> &mut CommonOptions {
        &mut self.common_options
    }

    fn compile(&self, mut ast: AST, rust_path: PathBuf) -> Vec<FileData> {
        let syntax = RustSyntax::with_edition(self.common_options.edition);
        let mut rust_helpers = HelperSet::<(), String>::default();
        let mut source_helpers = HelperSet::<SourceGroup, String>::default();
        let mut header_helpers = HelperSet::<HeaderGroup, String>::default();

        add_common_rust_helpers(&syntax, &mut rust_helpers);
        ast.rename_keywords(CPP_KEYWORDS);

        for (name, code) in [
            ("<algorithm>", "#include <algorithm>\n"),
            ("<memory>", "#include <memory>\n"),
            ("<optional>", "#include <optional>\n"),
            ("<stdint.h>", "#include <stdint.h>\n"),
            ("<stdlib.h>", "#include <stdlib.h>\n"),
            ("<string_view>", "#include <string_view>\n"),
            ("<string>", "#include <string>\n"),
            ("<tuple>", "#include <tuple>\n"),
            ("<variant>", "#include <variant>\n"),
            ("<vector>", "#include <vector>\n"),
        ] {
            source_helpers.add_group(SourceGroup::Include, name, code);
            header_helpers.add_group(HeaderGroup::Include, name, code);
        }

        source_helpers
            .add_group(
                SourceGroup::ExternCDecl,
                "_ffi_alloc",
                "void* _ffi_alloc(uintptr_t len);\n",
            )
            .add_dep_group(SourceGroup::Include, "<stdint.h>");

        source_helpers
            .add_group(
                SourceGroup::ExternCDecl,
                "_ffi_dealloc",
                "void _ffi_dealloc(const void* ptr, uintptr_t capacity);\n",
            )
            .add_dep_group(SourceGroup::Include, "<stdint.h>");

        source_helpers
            .add_group(
                SourceGroup::Anonymous,
                "_ffi_read",
                r#"
template <typename T>
T _ffi_read(const uint8_t* &ptr) {
    T val;
    memcpy(&val, ptr, sizeof(T));
    ptr += sizeof(T);
    return val;
}
"#,
            )
            .add_dep_group(SourceGroup::Include, "<stdint.h>");

        source_helpers
            .add_group(
                SourceGroup::Anonymous,
                "_ffi_write",
                r#"
template <typename T>
void _ffi_write(T val, std::vector<uint8_t> &buf) {
    buf.insert(buf.end(), (const uint8_t*)&val, (const uint8_t*)&val + sizeof(T));
}
"#,
            )
            .add_dep_group(SourceGroup::Include, "<stdint.h>")
            .add_dep_group(SourceGroup::Include, "<vector>");

        source_helpers
            .add_group(
                SourceGroup::Anonymous,
                "_ffi_vec_to_rust",
                r"
const void* _ffi_vec_to_rust(const std::vector<uint8_t>& vec) {
    return memcpy(_ffi_alloc(vec.size()), vec.data(), vec.size());
}
",
            )
            .add_dep_group(SourceGroup::Include, "<stdint.h>")
            .add_dep_group(SourceGroup::Include, "<vector>")
            .add_dep_group(SourceGroup::ExternCDecl, "_ffi_alloc");

        source_helpers
            .add_group(
                SourceGroup::Anonymous,
                "_ffi_string_to_rust",
                r"
const void* _ffi_string_to_rust(const std::string& str, uintptr_t &len) {
    len = str.size();
    return memcpy(_ffi_alloc(len), str.data(), len);
}
",
            )
            .add_dep_group(SourceGroup::Include, "<stdint.h>")
            .add_dep_group(SourceGroup::Include, "<string>")
            .add_dep_group(SourceGroup::ExternCDecl, "_ffi_alloc");

        source_helpers
            .add_group(
                SourceGroup::Anonymous,
                "_ffi_string_from_rust",
                r"
std::string _ffi_string_from_rust(const char* ptr, uintptr_t len, uintptr_t cap) {
    std::string str(ptr, len);
    _ffi_dealloc(ptr, cap);
    return str;
}
",
            )
            .add_dep_group(SourceGroup::Include, "<stdint.h>")
            .add_dep_group(SourceGroup::Include, "<string>")
            .add_dep_group(SourceGroup::ExternCDecl, "_ffi_dealloc");

        // Forward declarations
        for t in &ast.traits {
            header_helpers
                .add_group(
                    HeaderGroup::ForwardDecl,
                    &t.name,
                    format!("struct {};\n", t.name),
                )
                .set_is_forward_decl();
        }
        for s in &ast.structs {
            header_helpers
                .add_group(
                    HeaderGroup::ForwardDecl,
                    &s.name,
                    format!("struct {};\n", s.name),
                )
                .set_is_forward_decl();
        }
        for e in &ast.enums {
            header_helpers
                .add_group(
                    HeaderGroup::ForwardDecl,
                    &e.name,
                    format!("struct {};\n", e.name),
                )
                .set_is_forward_decl();
        }

        // Traits
        for t in &ast.traits {
            let mut deps = HashSet::new();
            let mut code = String::new();
            _ = write!(code, "\nstruct {} {{\n", t.name);
            _ = write!(code, "    virtual ~{}() {{}}\n", t.name);
            for f in &t.fns {
                code.push_str("    virtual ");
                CppTypeCtx {
                    cpp: &mut code,
                    ast: &ast,
                    deps: &mut deps,
                    include_group: HeaderGroup::Include,
                    decl_groups: Some(DeclGroups {
                        forward: HeaderGroup::ForwardDecl,
                        full: HeaderGroup::Other,
                    }),
                    loc: TypeLoc::InsideRustNamespace,
                    ns: &self.namespace,
                }
                .append_cpp_signature(
                    f.returns.as_ref().map(|r| &r.ty),
                    &f.name,
                    None,
                    &f.args,
                );
                code.push_str(" = 0;\n");
            }
            code.push_str("};\n");
            header_helpers
                .add_group(HeaderGroup::Other, &t.name, code)
                .add_forward_decl_group(HeaderGroup::ForwardDecl, &t.name)
                .add_deps_group(deps)
                .mark_used();
        }

        // Enums
        for e in &ast.enums {
            let mut code = String::new();
            let mut enum_deps = HashSet::new();
            if !e.has_fields() {
                // Enums without fields are just integers
                _ = write!(code, "\nenum struct {} : int32_t", e.name);
                code.push_str(" {\n");
                for v in &e.variants {
                    if v.discriminant == std::i32::MIN {
                        // Avoid a Visual C++ warning
                        _ = write!(code, "    {} = {} - 1,\n", v.name, v.discriminant + 1);
                    } else {
                        _ = write!(code, "    {} = {},\n", v.name, v.discriminant);
                    }
                }
                code.push_str("};\n");
            } else {
                // Enums with fields map to "std::variant"
                _ = write!(code, "\nstruct {} : std::variant<std::monostate", e.name);
                for v in &e.variants {
                    _ = write!(code, ", detail::{}__{}", e.name, v.name);
                }
                code.push_str("> {\n");
                for v in &e.variants {
                    _ = write!(
                        code,
                        "    using {} = detail::{}__{};\n",
                        v.name, e.name, v.name
                    );
                }
                _ = write!(code, "    using std::variant<std::monostate");
                for v in &e.variants {
                    _ = write!(code, ", {}", v.name);
                }
                code.push_str(">::operator =;\n");
                code.push_str(
                    "    template <typename T> bool is() const { return std::holds_alternative<T>(*this); }\n",
                );
                code.push_str(
                    "    template <typename T> const T* as() const { return std::get_if<T>(this); }\n",
                );
                code.push_str(
                    "    template <typename T> T* as() { return std::get_if<T>(this); }\n",
                );
                code.push_str("};\n");
                enum_deps.insert((HeaderGroup::Include, "<variant>".to_string()));

                // Declarations for the variants need to be written out separately
                let mut detail = String::new();
                let mut detail_deps = HashSet::new();
                let detail_name = format!("detail::{}", e.name);
                _ = write!(detail, "\nnamespace detail {{\n");
                for v in &e.variants {
                    _ = write!(detail, "\nstruct {}__{} {{\n", e.name, v.name);
                    for f in &v.fields {
                        detail.push_str("    ");
                        CppTypeCtx {
                            cpp: &mut detail,
                            ast: &ast,
                            deps: &mut detail_deps,
                            include_group: HeaderGroup::Include,
                            decl_groups: Some(DeclGroups {
                                forward: HeaderGroup::ForwardDecl,
                                full: HeaderGroup::Other,
                            }),
                            loc: TypeLoc::InsideRustNamespace,
                            ns: &self.namespace,
                        }
                        .append_cpp_type(&f.ty, CppDecl::Full);
                        _ = write!(
                            detail,
                            " {}{};\n",
                            with_digit_prefix(&f.name),
                            cpp_struct_field_init(&ast, &f.ty)
                        );
                    }
                    if e.derives_partial_eq {
                        generate_operator_eq(
                            &mut source_helpers,
                            &format!("{}::detail", self.namespace),
                            &format!("{}__{}", e.name, v.name),
                            &v.fields,
                            &mut detail,
                        );
                    }
                    detail.push_str("};\n");
                }
                _ = write!(detail, "\n}} // namespace detail\n");
                header_helpers
                    .add_group(HeaderGroup::Other, &detail_name, detail)
                    .add_deps_group(detail_deps);
                enum_deps.insert((HeaderGroup::Other, detail_name));
            }
            header_helpers
                .add_group(HeaderGroup::Other, &e.name, code)
                .add_deps_group(enum_deps)
                .mark_used();
        }

        // Structs
        for s in &ast.structs {
            let mut deps = HashSet::new();
            let mut code = String::new();
            _ = write!(code, "\nstruct {}", s.name);
            code.push_str(" {\n");
            for f in &s.fields {
                code.push_str("    ");
                CppTypeCtx {
                    cpp: &mut code,
                    ast: &ast,
                    deps: &mut deps,
                    include_group: HeaderGroup::Include,
                    decl_groups: Some(DeclGroups {
                        forward: HeaderGroup::ForwardDecl,
                        full: HeaderGroup::Other,
                    }),
                    loc: TypeLoc::InsideRustNamespace,
                    ns: &self.namespace,
                }
                .append_cpp_type(&f.ty, CppDecl::Full);
                _ = write!(
                    code,
                    " {}{};\n",
                    with_digit_prefix(&f.name),
                    cpp_struct_field_init(&ast, &f.ty)
                );
            }
            if s.derives_partial_eq {
                generate_operator_eq(
                    &mut source_helpers,
                    &self.namespace,
                    &s.name,
                    &s.fields,
                    &mut code,
                );
            }
            code.push_str("};\n");
            header_helpers
                .add_group(HeaderGroup::Other, &s.name, code)
                .add_forward_decl_group(HeaderGroup::ForwardDecl, &s.name)
                .add_deps_group(deps)
                .mark_used();
        }

        // Constants
        for c in &ast.consts {
            let mut deps = HashSet::new();
            let mut code = String::new();
            CppTypeCtx {
                cpp: &mut code,
                ast: &ast,
                deps: &mut deps,
                include_group: HeaderGroup::Include,
                decl_groups: Some(DeclGroups {
                    forward: HeaderGroup::ForwardDecl,
                    full: HeaderGroup::Other,
                }),
                loc: TypeLoc::ForConstant,
                ns: &self.namespace,
            }
            .append_cpp_type(&c.ty, CppDecl::Full);
            _ = write!(code, " const {} = ", c.name);
            append_cpp_val(&mut code, &c.val);
            code.push_str(";\n");
            header_helpers
                .add_group(HeaderGroup::Constants, &c.name, code)
                .add_deps_group(deps)
                .mark_used();
        }

        let mut ctx = CppCtx {
            syntax,
            namespace: self.namespace.clone(),
            rust_helpers,
            source_helpers,
            header_helpers,
            ..CppCtx::default()
        };
        let mut header_fn_decls = String::new();

        // Functions
        for f in &ast.fns {
            generate_cpp_to_rust_fn(&ast, &mut ctx, f, &mut header_fn_decls, None);
        }

        // Determine the path from the source to the header
        let path_to_header = path_relative_from(
            &self.header_path,
            &self.source_path.parent().unwrap_or(Path::new("")),
        );
        let path_to_header = path_to_header.as_ref().unwrap_or(&self.header_path);
        let path_to_header = format!("{:?}", path_to_header.display());

        // Assemble the Rust code
        let mut rust = format!("// {DO_NOT_EDIT_COMMENT}\n");
        for it in ctx.rust_helpers.code_in_order() {
            rust.push_str(it);
        }

        // Assemble the C++ header
        let mut includes = HashSet::new();
        let mut header = format!("// {DO_NOT_EDIT_COMMENT}\n");
        let header_code = ctx.header_helpers.code_by_group_in_order();
        header.push_str("\n#pragma once\n");
        if let Some(code) = header_code.get(&HeaderGroup::Include) {
            header.push('\n');
            for it in code {
                includes.insert(it);
                header.push_str(it);
            }
        }
        header.push_str("\nnamespace rust {\n");
        if let Some(code) = header_code.get(&HeaderGroup::ForwardDecl) {
            header.push('\n');
            for it in code {
                header.push_str(it);
            }
        }
        if let Some(code) = header_code.get(&HeaderGroup::Other) {
            for it in code {
                header.push_str(it);
            }
        }
        if let Some(code) = header_code.get(&HeaderGroup::Constants) {
            header.push('\n');
            for it in code {
                header.push_str(it);
            }
        }
        header.push_str(&header_fn_decls);
        header.push_str("\n} // namespace rust\n");

        // Assemble the C++ source
        let mut source = format!("// {DO_NOT_EDIT_COMMENT}\n");
        let source_code = ctx.source_helpers.code_by_group_in_order();
        _ = write!(source, "\n#include {path_to_header}\n");
        if let Some(code) = source_code.get(&SourceGroup::Include) {
            for it in code {
                if !includes.contains(it) {
                    source.push_str(it);
                }
            }
        }
        if let Some(code) = source_code.get(&SourceGroup::MultiRet) {
            for it in code {
                source.push_str(it);
            }
        }
        if let Some(code) = source_code.get(&SourceGroup::ExternCDecl) {
            source.push_str("\nextern \"C\" {\n\n");
            for it in code {
                source.push_str(it);
            }
            source.push_str("\n} // extern \"C\"\n");
        }
        if let Some(code) = source_code.get(&SourceGroup::Anonymous) {
            source.push_str("\nnamespace {\n");
            for it in code {
                source.push_str(it);
            }
            source.push_str("\n} // namespace\n");
        }
        if let Some(code) = source_code.get(&SourceGroup::ExternCImpl) {
            source.push_str("\nextern \"C\" {\n");
            for it in code {
                source.push_str(it);
            }
            source.push_str("\n} // extern \"C\"\n");
        }
        if let Some(code) = source_code.get(&SourceGroup::Other) {
            for it in code {
                source.push_str(it);
            }
        }

        vec![
            FileData {
                path: rust_path,
                contents: rust,
            },
            FileData {
                path: self.source_path.clone(),
                contents: source,
            },
            FileData {
                path: self.header_path.clone(),
                contents: header,
            },
        ]
    }
}

// C++ struct fields without an initializer are uninitialized, which means they
// start off being random garbage. This can lead to undefined behavior and
// security vulnerabilities. Always initialize all struct fields to avoid that.
fn cpp_struct_field_init(ast: &AST, ty: &RustType) -> &'static str {
    use RustType::*;
    match ty {
        Bool => " = false",
        U8 | U16 | U32 | Usize | U64 | I8 | I16 | I32 | Isize | I64 => " = 0",
        F32 => " = 0.0f",
        F64 => " = 0.0",
        Enum(enum_index) if !ast.enums[*enum_index].has_fields() => "{}",
        _ => "",
    }
}

#[derive(Default)]
struct CppCtx {
    syntax: RustSyntax,
    namespace: String,
    helper_names: NameSet,
    rust_helpers: HelperSet<(), String>,
    header_helpers: HelperSet<HeaderGroup, String>,
    source_helpers: HelperSet<SourceGroup, String>,
    multi_ret_helpers: HashMap<Vec<RustType>, String>,
    trait_to_rust_helpers: HashMap<(RustPtr, usize), String>,
    trait_to_cpp_helpers: HashMap<(RustPtr, usize), String>,
    vec_to_rust_helpers: HashMap<RustType, (String, String)>,
    vec_to_cpp_helpers: HashMap<RustType, (String, String)>,
    box_to_rust_helpers: HashMap<RustType, (String, String)>,
    box_to_cpp_helpers: HashMap<RustType, (String, String)>,
    enum_to_rust_helpers: HashMap<usize, (String, String)>,
    enum_to_cpp_helpers: HashMap<usize, (String, String)>,
}

#[derive(Default)]
struct Transform {
    cpp: FnBuilder,
    rust: FnBuilder,
    ffi_args: Vec<RustArg>,
    buf: Option<Rc<SharedBuf>>,
    buf_status: BufStatus,
    buf_ref: &'static str,
}

struct TraitInfo<'a> {
    t: &'a RustTrait,
    kind: RustPtr,
}

impl TraitInfo<'_> {
    fn self_type(&self, ns: &str) -> RustType {
        RustType::Verbatim(match self.kind {
            RustPtr::Box => format!("{ns}::{}*", self.t.name),
            RustPtr::Rc => format!("std::shared_ptr<{ns}::{}>*", self.t.name),
        })
    }

    fn cpp_name(&self) -> String {
        format!("_ffi_{:?}_{}", self.kind, self.t.name)
    }
}

fn generate_cpp_to_rust_fn(
    ast: &AST,
    ctx: &mut CppCtx,
    f: &RustFn,
    header: &mut String,
    trait_info: Option<TraitInfo>,
) {
    let ffi_name = ctx.helper_names.create(&match &trait_info {
        None => format!("_ffi_fn_{}", f.name),
        Some(info) => format!("_ffi_{:?}_{}__{}", info.kind, info.t.name, f.name),
    });
    let mut names = NameSet::default();
    for arg in &f.args {
        names.add(arg.name.clone());
    }
    if let Some(ret) = &f.returns {
        names.add(ret.name.clone());
    }
    let mut source_deps = HashSet::new();

    // Transform the arguments
    let mut arg_tfm = Transform::default();
    if let Some(info) = &trait_info {
        arg_tfm.rust.line(format!(
            "let _self = unsafe {{ &*(_self as *const {}<dyn {}>) }};",
            info.kind.path(),
            info.t.name
        ));
    }
    for arg in &f.args {
        arg_tfm.cpp.mark_pure(&arg.name);
        transform_to_rust(
            ast,
            ctx,
            &mut names,
            &mut arg_tfm,
            &arg.name,
            &arg.ty,
            &mut source_deps,
        );
    }
    arg_tfm.cpp.insert_deferred_lines_here();

    // Generate the Rust call to the FFI function
    let mut rust_call = String::new();
    if trait_info.is_some() {
        rust_call.push_str("_self.");
    }
    _ = write!(rust_call, "{}(", f.name);
    rust_call.push_str(&arg_tfm.rust.find_args(&f.args, RefInline));
    rust_call.push(')');

    // Transform the result
    let mut ret_tfm = Transform::default();
    if let Some(ret) = &f.returns {
        ret_tfm.rust.decl(&ret.name, rust_call);
        transform_to_cpp(
            ast,
            ctx,
            &mut names,
            &mut ret_tfm,
            &ret.name,
            &ret.ty,
            &mut source_deps,
        );
    } else {
        rust_call.push(';');
        ret_tfm.rust.line(rust_call);
    }

    // Generate the C++ call to the FFI function
    let mut cpp_call = format!("{ffi_name}(");
    if trait_info.is_some() {
        cpp_call.push_str("_self");
        if !arg_tfm.ffi_args.is_empty() {
            cpp_call.push_str(", ");
        }
    }
    cpp_call.push_str(&arg_tfm.cpp.find_args(&arg_tfm.ffi_args, RefStdMove));
    cpp_call.push(')');

    // Header
    {
        let mut header_deps = HashSet::new();
        if trait_info.is_none() {
            header.push('\n');
        }
        CppTypeCtx {
            cpp: header,
            ast,
            deps: &mut header_deps,
            include_group: HeaderGroup::Include,
            decl_groups: None,
            loc: match trait_info {
                None => TypeLoc::InsideRustNamespace,
                Some(_) => TypeLoc::OutsideRustNamespace,
            },
            ns: &ctx.namespace,
        }
        .append_cpp_signature(f.returns.as_ref().map(|r| &r.ty), &f.name, None, &f.args);
        header.push_str(";\n");
        ctx.header_helpers.mark_all_used_group(header_deps);
    }

    // Source: Other
    {
        // Handle the return values
        let mut fb = arg_tfm.cpp;
        match &ret_tfm.ffi_args[..] {
            [] => {
                cpp_call.push(';');
                fb.line(cpp_call);
            }
            [arg] => fb.decl(&arg.name, cpp_call),
            _ => {
                let ret = names.create("multi_ret");
                fb.decl(&ret, cpp_call);
                for (i, arg) in ret_tfm.ffi_args.iter().enumerate() {
                    fb.decl(&arg.name, format!("{ret}._{i}"));
                }
            }
        };
        fb.extend(ret_tfm.cpp);
        fb.insert_deferred_lines_here();
        if let Some(ret) = &f.returns {
            let code = fb.find(&ret.name, &ret.ty, RefInline).code;
            fb.line(format!("return {code};"));
        }

        // Write out the final function
        let mut source = String::new();
        let fn_name = &match &trait_info {
            None => format!("{}::{}", ctx.namespace, f.name),
            Some(info) => format!("{}::{}", info.cpp_name(), f.name),
        };
        source.push('\n');
        CppTypeCtx {
            cpp: &mut source,
            ast,
            deps: &mut source_deps,
            include_group: SourceGroup::Include,
            decl_groups: None,
            loc: TypeLoc::OutsideRustNamespace,
            ns: &ctx.namespace,
        }
        .append_cpp_signature(f.returns.as_ref().map(|r| &r.ty), fn_name, None, &f.args);
        source.push_str(" {\n");
        fb.write_to_cpp(ctx, ast, &mut source_deps, &mut source, "    ");
        source.push_str("}\n");
        source_deps.insert((SourceGroup::ExternCDecl, ffi_name.clone()));
        ctx.source_helpers
            .add_group(SourceGroup::Other, &fn_name, source)
            .add_deps_group(source_deps)
            .mark_used();
    }

    // Source: ExternCDecl
    {
        let mut source_deps = HashSet::new();
        let mut source = String::new();
        let return_ty = match &ret_tfm.ffi_args[..] {
            [] => None,
            [arg] => Some(Cow::Borrowed(&arg.ty)),
            _ => {
                let ty_name = multi_ret_helper(ast, ctx, &ret_tfm.ffi_args);
                source_deps.insert((SourceGroup::MultiRet, ty_name.clone()));
                Some(Cow::Owned(RustType::Verbatim(ty_name)))
            }
        };
        CppTypeCtx {
            cpp: &mut source,
            ast,
            deps: &mut source_deps,
            include_group: SourceGroup::Include,
            decl_groups: None,
            loc: TypeLoc::OutsideRustNamespace,
            ns: &ctx.namespace,
        }
        .append_cpp_signature(
            return_ty.as_deref(),
            &ffi_name,
            trait_info
                .as_ref()
                .map(|_| RustArg {
                    name: "_self".into(),
                    ty: RustType::ForeignHandle,
                })
                .as_ref(),
            &arg_tfm.ffi_args,
        );
        source.push_str(";\n");
        ctx.source_helpers
            .add_group(SourceGroup::ExternCDecl, &ffi_name, source)
            .add_deps_group(source_deps);
    }

    // Rust
    {
        // Handle the return values
        let mut fb = arg_tfm.rust;
        fb.extend(ret_tfm.rust);
        fb.insert_deferred_lines_here();
        match &ret_tfm.ffi_args[..] {
            [] => {}
            [arg] => {
                let code = fb.find(&arg.name, &arg.ty, RefInline).code;
                fb.line(code);
            }
            _ => {
                let ty_name = multi_ret_helper(ast, ctx, &ret_tfm.ffi_args);
                let args = fb.find_args(&ret_tfm.ffi_args, RefInline);
                fb.line(format!("{ty_name}({args})"));
            }
        }

        // Write out the final function
        let mut rust = String::new();
        _ = write!(rust, "\n{}\n", ctx.syntax.unsafe_no_mangle());
        _ = write!(rust, "extern \"C\" fn {ffi_name}(");
        if trait_info.is_some() {
            rust.push_str("_self: *const u8");
        }
        for (i, arg) in arg_tfm.ffi_args.iter().enumerate() {
            if trait_info.is_some() || i > 0 {
                rust.push_str(", ");
            }
            _ = write!(rust, "{}: ", arg.name);
            append_rust_type(&mut rust, ast, &arg.ty);
        }
        rust.push(')');
        match &ret_tfm.ffi_args[..] {
            [] => {}
            [arg] => {
                rust.push_str(" -> ");
                append_rust_type(&mut rust, ast, &arg.ty);
            }
            _ => {
                let ty_name = multi_ret_helper(ast, ctx, &ret_tfm.ffi_args);
                _ = write!(rust, " -> {ty_name}");
            }
        }
        rust.push_str(" {\n");
        fb.write_to_rust(ast, &mut rust, "    ");
        rust.push_str("}\n");
        ctx.rust_helpers.add(&ffi_name, rust).mark_used();
    }
}

fn generate_rust_to_cpp_fn(
    ast: &AST,
    ctx: &mut CppCtx,
    kind: RustPtr,
    t: &RustTrait,
    f: &RustFn,
    rust: &mut String,
) {
    let ffi_name = ctx
        .helper_names
        .create(&format!("_ffi_cpp_{kind:?}_{}__{}", t.name, f.name));
    let mut names = NameSet::default();
    for arg in &f.args {
        names.add(arg.name.clone());
    }
    if let Some(ret) = &f.returns {
        names.add(ret.name.clone());
    }
    let mut source_deps = HashSet::new();

    // Transform the arguments
    let mut arg_tfm = Transform::default();
    for arg in &f.args {
        arg_tfm.rust.mark_pure(&arg.name);
        transform_to_cpp(
            ast,
            ctx,
            &mut names,
            &mut arg_tfm,
            &arg.name,
            &arg.ty,
            &mut source_deps,
        );
    }
    arg_tfm.rust.insert_deferred_lines_here();

    // Generate the C++ call to the API function
    let mut cpp_call = String::new();
    cpp_call.push_str(match kind {
        RustPtr::Box => "_self",
        RustPtr::Rc => "_self->get()",
    });
    _ = write!(cpp_call, "->{}(", f.name);
    cpp_call.push_str(&arg_tfm.cpp.find_args(&f.args, RefStdMove));
    cpp_call.push(')');

    // Transform the result
    let mut ret_tfm = Transform::default();
    if let Some(ret) = &f.returns {
        ret_tfm.cpp.decl(&ret.name, cpp_call);
        transform_to_rust(
            ast,
            ctx,
            &mut names,
            &mut ret_tfm,
            &ret.name,
            &ret.ty,
            &mut source_deps,
        );
    } else {
        cpp_call.push(';');
        ret_tfm.cpp.line(cpp_call);
    }

    // Generate the Rust call to the FFI function
    let mut rust_call = format!("unsafe {{ {ffi_name}(self.0");
    if !arg_tfm.ffi_args.is_empty() {
        rust_call.push_str(", ");
    }
    rust_call.push_str(&arg_tfm.rust.find_args(&arg_tfm.ffi_args, RefInline));
    rust_call.push_str(") }");

    // Rust
    {
        // Handle the return values
        let mut fb = arg_tfm.rust;
        match &ret_tfm.ffi_args[..] {
            [] => {
                rust_call.push(';');
                fb.line(rust_call);
            }
            [arg] => fb.decl(&arg.name, rust_call),
            _ => {
                let ret = names.create("multi_ret");
                fb.decl(&ret, rust_call);
                for (i, arg) in ret_tfm.ffi_args.iter().enumerate() {
                    fb.decl(&arg.name, format!("{ret}.{i}"));
                }
            }
        };
        fb.extend(ret_tfm.rust);
        fb.insert_deferred_lines_here();
        if let Some(ret) = &f.returns {
            let code = fb.find(&ret.name, &ret.ty, RefInline).code;
            fb.line(code);
        }

        // Write out the final function
        _ = write!(rust, "\n    fn {}(&self", f.name);
        for arg in &f.args {
            _ = write!(rust, ", {}: ", arg.name);
            append_rust_type(rust, ast, &arg.ty);
        }
        rust.push(')');
        if let Some(returns) = &f.returns {
            rust.push_str(" -> ");
            append_rust_type(rust, ast, &returns.ty);
        }
        rust.push_str(" {\n");
        _ = write!(
            rust,
            "        {} \"C\" {{ fn {ffi_name}(_: *const u8",
            ctx.syntax.unsafe_extern()
        );
        for arg in &arg_tfm.ffi_args {
            _ = write!(rust, ", {}: ", arg.name);
            append_rust_type(rust, ast, &arg.ty);
        }
        match &ret_tfm.ffi_args[..] {
            [] => rust.push(')'),
            [arg] => {
                rust.push_str(") -> ");
                append_rust_type(rust, ast, &arg.ty);
            }
            _ => {
                let ty_name = multi_ret_helper(ast, ctx, &ret_tfm.ffi_args);
                _ = write!(rust, ") -> {ty_name}");
            }
        }
        rust.push_str("; }\n");
        fb.write_to_rust(ast, rust, "        ");
        rust.push_str("    }\n");
    }

    // Source: ExternCImpl
    {
        // Handle the return values
        let mut fb = arg_tfm.cpp;
        fb.extend(ret_tfm.cpp);
        fb.insert_deferred_lines_here();
        let return_ty = match &ret_tfm.ffi_args[..] {
            [] => None,
            [arg] => {
                let code = fb.find(&arg.name, &arg.ty, RefInline).code;
                fb.line(format!("return {code};"));
                Some(Cow::Borrowed(&arg.ty))
            }
            _ => {
                let ty_name = multi_ret_helper(ast, ctx, &ret_tfm.ffi_args);
                let args = fb.find_args(&ret_tfm.ffi_args, RefStdMove);
                fb.line(format!("return {ty_name}{{{args}}};"));
                source_deps.insert((SourceGroup::MultiRet, ty_name.clone()));
                Some(Cow::Owned(RustType::Verbatim(ty_name)))
            }
        };

        // Write out the final function
        let mut source = String::new();
        source.push('\n');
        CppTypeCtx {
            cpp: &mut source,
            ast,
            deps: &mut source_deps,
            include_group: SourceGroup::Include,
            decl_groups: None,
            loc: TypeLoc::OutsideRustNamespace,
            ns: &ctx.namespace,
        }
        .append_cpp_signature(
            return_ty.as_deref(),
            &ffi_name,
            Some(&RustArg {
                name: "_self".into(),
                ty: TraitInfo { t, kind }.self_type(&ctx.namespace),
            }),
            &arg_tfm.ffi_args,
        );
        source.push_str(" {\n");
        fb.write_to_cpp(ctx, ast, &mut source_deps, &mut source, "    ");
        source.push_str("}\n");
        ctx.source_helpers
            .add_group(SourceGroup::ExternCImpl, &ffi_name, source)
            .add_deps_group(source_deps)
            .mark_used();
    }
}

fn generate_operator_eq(
    source_helpers: &mut HelperSet<SourceGroup, String>,
    ns: &str,
    name: &str,
    fields: &[RustField],
    header: &mut String,
) {
    use RustType::*;

    fn cpp_type_contains_box(ty: &RustType) -> bool {
        match ty {
            Pair { other, .. } => cpp_type_contains_box(other),
            Vector(inner_ty) => cpp_type_contains_box(inner_ty),
            Optional(inner_ty) => cpp_type_contains_box(inner_ty),
            Ptr(kind, inner_ty) if *kind == RustPtr::Box => match &**inner_ty {
                DynTrait(_) => false,
                _ => true,
            },
            Tuple(types) => types.iter().any(cpp_type_contains_box),
            _ => false,
        }
    }

    fn emit_eq(
        parts: &mut Vec<String>,
        ty: &RustType,
        a: &str,
        b: &str,
        source_deps: &mut HashSet<(SourceGroup, String)>,
    ) {
        if !cpp_type_contains_box(ty) {
            parts.push(format!("{a} == {b}"));
            return;
        }

        match ty {
            Pair { other, .. } => emit_eq(parts, other, a, b, source_deps),

            Tuple(types) => {
                for (i, item_ty) in types.iter().enumerate() {
                    let a = format!("std::get<{i}>({a})");
                    let b = format!("std::get<{i}>({b})");
                    emit_eq(parts, item_ty, &a, &b, source_deps);
                }
            }

            Ptr(_, inner_ty) => {
                let a = format!("*{a}");
                let b = format!("*{b}");
                emit_eq(parts, inner_ty, &a, &b, source_deps);
            }

            Optional(inner_ty) => {
                let mut inner_parts = Vec::new();
                let inner_a = format!("*{a}");
                let inner_b = format!("*{b}");
                emit_eq(&mut inner_parts, inner_ty, &inner_a, &inner_b, source_deps);
                parts.push(if inner_parts.is_empty() {
                    format!("!{a} == !{b}")
                } else {
                    format!("({a} && {b} ? {} : !{a} && !{b})", inner_parts.join(" && "))
                });
            }

            Vector(inner_ty) => {
                let mut inner_parts = Vec::new();
                emit_eq(&mut inner_parts, inner_ty, "a", "b", source_deps);
                parts.push(if inner_parts.is_empty() {
                    format!("{a}.size() == {b}.size()")
                } else {
                    source_deps.insert((SourceGroup::Include, "<algorithm>".into())); // For "std::equal"
                    let a = if a.starts_with('*') {
                        Cow::Owned(format!("({a})"))
                    } else {
                        Cow::Borrowed(a)
                    };
                    let b = if b.starts_with('*') {
                        Cow::Owned(format!("({b})"))
                    } else {
                        Cow::Borrowed(b)
                    };
                    format!(
                        "std::equal({a}.begin(), {a}.end(), {b}.begin(), {b}.end(), \
                        [](const auto& a, const auto& b) {{ return {}; }})",
                        inner_parts.join(" && ")
                    )
                });
            }

            _ => parts.push(format!("{a} == {b}")),
        }
    }

    let mut names = NameSet::default();
    for f in fields {
        names.add(with_digit_prefix(&f.name).to_string());
    }
    let other = names.create(
        &name
            .chars()
            .next()
            .unwrap()
            .to_ascii_lowercase()
            .to_string(),
    );
    let mut parts = Vec::new();
    let mut source_deps = HashSet::new();

    for f in fields {
        let a = with_digit_prefix(&f.name);
        let b = format!("{other}.{a}");
        emit_eq(&mut parts, &f.ty, &a, &b, &mut source_deps);
    }

    if parts.is_empty() {
        _ = write!(
            header,
            "    bool operator == (const {name}&) const {{ return true; }}\n"
        );
    } else {
        let mut source =
            format!("\nbool {ns}::{name}::operator == (const {ns}::{name}& {other}) const {{\n");
        if parts.len() == 1 || parts.iter().map(|x| x.len()).sum::<usize>() < 100 {
            _ = write!(source, "    return {};\n", parts.join(" && "));
        } else {
            source.push_str("    return (");
            for (i, part) in parts.iter().enumerate() {
                if i > 0 {
                    source.push_str(" &&");
                }
                source.push_str("\n        ");
                source.push_str(part);
            }
            source.push_str("\n    );\n");
        }
        source.push_str("}\n");
        _ = write!(header, "    bool operator == (const {name}&) const;\n");
        source_helpers
            .add_group(SourceGroup::Other, &format!("{name}::operator =="), source)
            .add_deps_group(source_deps)
            .mark_used();
    }

    _ = write!(
        header,
        "    bool operator != (const {name}& {other}) const {{ return !(*this == {other}); }}\n"
    );
}

fn transform_to_rust(
    ast: &AST,
    ctx: &mut CppCtx,
    names: &mut NameSet,
    tfm: &mut Transform,
    name: &str,
    ty: &RustType,
    source_deps: &mut HashSet<(SourceGroup, String)>,
) {
    use RustType::*;

    fn add_ffi_arg(
        ast: &AST,
        ctx: &mut CppCtx,
        tfm: &mut Transform,
        source_deps: &mut HashSet<(SourceGroup, String)>,
        name: &str,
        ty: &RustType,
    ) {
        match tfm.buf_status {
            BufStatus::Outside => tfm.ffi_args.push(RustArg {
                name: name.to_string(),
                ty: ty.clone(),
            }),
            BufStatus::Inside => {
                let buf = tfm.buf.as_ref().unwrap();

                // C++ (write)
                let code = tfm.cpp.find(name, ty, RefStdMove).code;
                tfm.cpp
                    .line(format!("_ffi_write({code}, {});", buf.buf_name()));
                source_deps.insert((SourceGroup::Anonymous, "_ffi_write".into()));

                // Rust (read)
                let mut rust = "_ffi_read::<".to_string();
                append_rust_type(&mut rust, ast, ty);
                _ = write!(rust, ">({}{})", tfm.buf_ref, buf.end_name());
                tfm.rust.decl(name, rust);
                ctx.rust_helpers.mark_used("_ffi_read");
            }
        }
    }

    match ty {
        Bool | U8 | U16 | U32 | Usize | U64 | I8 | I16 | I32 | Isize | I64 | F32 | F64
        | ForeignHandle => add_ffi_arg(ast, ctx, tfm, source_deps, name, ty),

        RefStr | OwnStr => {
            let cpp_code = tfm.cpp.find(name, ty, RefInline).code;
            let ptr_name = names.create(&format!("{name}_ptr"));
            let len_name = names.create(&format!("{name}_len"));
            let opt_ref = match ty {
                RefStr => "&",
                _ => "",
            };
            tfm.cpp.line(format!("uintptr_t {len_name};"));
            tfm.cpp.line(format!(
                "const void* {ptr_name} = _ffi_string_to_rust({cpp_code}, {len_name});"
            ));
            ctx.source_helpers
                .mark_used_group(SourceGroup::Anonymous, "_ffi_string_to_rust");
            add_ffi_arg(ast, ctx, tfm, source_deps, &ptr_name, &ForeignHandle);
            add_ffi_arg(ast, ctx, tfm, source_deps, &len_name, &Usize);
            let len_code = tfm.rust.find(&len_name, &Usize, RefInline).code;
            let ptr_code = tfm.rust.find(&ptr_name, &ForeignHandle, RefInline).code;
            tfm.rust.decl(
                name,
                format!("{opt_ref}_ffi_string_from_host({ptr_code}, {len_code})"),
            );
            ctx.rust_helpers.mark_used("_ffi_string_from_host");
        }

        Enum(enum_index) => {
            let e = &ast.enums[*enum_index];
            let (cpp_helper, rust_helper) = enum_to_rust_helper(ast, ctx, *enum_index);
            if !e.has_fields() {
                let cpp = tfm.cpp.find(name, ty, RefInline);
                let raw_name = names.create(&format!("{name}_raw"));
                tfm.cpp
                    .maybe_pure_decl(cpp.pure, &raw_name, format!("int32_t({})", cpp.code));
                add_ffi_arg(ast, ctx, tfm, source_deps, &raw_name, &I32);
                tfm.rust.decl(name, format!("{rust_helper}({raw_name})"));
            } else {
                let cpp = tfm.cpp.find(name, ty, RefStdMove);
                let buf = ensure_cpp_buf(ctx, names, tfm, source_deps);
                tfm.cpp
                    .line(format!("{cpp_helper}({}, {});", cpp.code, buf.buf_name()));
                source_deps.insert((SourceGroup::Anonymous, cpp_helper));
                tfm.rust.decl(
                    name,
                    format!("{rust_helper}({}{})", tfm.buf_ref, buf.end_name()),
                );
            }
        }

        Struct(struct_index) => {
            let cpp = tfm.cpp.find(name, ty, RefMany);
            let s = &ast.structs[*struct_index];
            let mut item_names = Vec::new();
            for f in &s.fields {
                let item_name = names.create(&format!("{name}_{}", f.name));
                tfm.cpp.maybe_pure_decl(
                    cpp.pure,
                    &item_name,
                    format!("{}.{}", cpp.code, with_digit_prefix(&f.name)),
                );
                transform_to_rust(ast, ctx, names, tfm, &item_name, &f.ty, source_deps);
                item_names.push(item_name.into());
            }
            if s.fields.is_empty() {
                // Avoid an unused variable warning in C++
                let code = tfm.cpp.find(name, ty, RefInline).code;
                tfm.cpp.line(format!("(void){code};"));
            }
            rust_decl_ctor(&mut tfm.rust, name, &s.name, &s.fields, item_names);
        }

        Tuple(types) => {
            let cpp = tfm.cpp.find(name, ty, RefMany);
            let mut item_args = Vec::new();
            for (i, item_ty) in types.iter().enumerate() {
                let item_name = names.create(&format!("{name}_{i}"));
                tfm.cpp.maybe_pure_decl(
                    cpp.pure,
                    &item_name,
                    format!("std::get<{i}>({})", cpp.code),
                );
                transform_to_rust(ast, ctx, names, tfm, &item_name, &item_ty, source_deps);
                item_args.push(RustArg {
                    name: item_name,
                    ty: item_ty.clone(),
                });
            }
            if types.is_empty() {
                // Avoid an unused variable warning in C++
                let code = tfm.cpp.find(name, ty, RefInline).code;
                tfm.cpp.line(format!("(void){code};"));
            }
            let mut rust_code = tfm.rust.find_args(&item_args, RefInline);
            if types.len() == 1 {
                rust_code.push(',');
            }
            tfm.rust.decl(name, format!("({rust_code})"));
        }

        Ptr(kind, inner_ty) => {
            if let DynTrait(trait_index) = &**inner_ty {
                let cpp_code = tfm.cpp.find(name, ty, RefInline).code;
                let ptr_name = names.create(&format!("{name}_ptr"));
                let rust_helper = trait_to_rust_helper(ast, ctx, *trait_index, *kind);
                let cpp_code = match kind {
                    RustPtr::Box => format!("{cpp_code}.release()"),
                    RustPtr::Rc => format!(
                        "new std::shared_ptr<{}::{}>({cpp_code})",
                        ctx.namespace, ast.traits[*trait_index].name
                    ),
                };
                tfm.cpp.decl(&ptr_name, cpp_code);
                add_ffi_arg(ast, ctx, tfm, source_deps, &ptr_name, &ForeignHandle);
                let ptr_code = tfm.rust.find(&ptr_name, &ForeignHandle, RefInline).code;
                tfm.rust.decl(
                    name,
                    format!("{}::new({rust_helper}({ptr_code}))", kind.path()),
                );
            } else if *kind == RustPtr::Box {
                let cpp_code = tfm.cpp.find(name, ty, RefMany).code;
                let (cpp_helper, rust_helper) = box_to_rust_helper(ast, ctx, inner_ty);
                let buf = ensure_cpp_buf(ctx, names, tfm, source_deps);
                tfm.cpp.line(format!(
                    "{cpp_helper}(std::move(*{cpp_code}), {});",
                    buf.buf_name()
                ));
                source_deps.insert((SourceGroup::Anonymous, cpp_helper));
                tfm.rust.decl(
                    name,
                    format!("{rust_helper}({}{})", tfm.buf_ref, buf.end_name()),
                );
            } else {
                unreachable!()
            }
        }

        Vector(inner_ty) => {
            let cpp_code = tfm.cpp.find(name, ty, RefMany).code;
            let len_name = names.create(&format!("{name}_len"));
            let (cpp_helper, rust_helper) = vec_to_rust_helper(ast, ctx, inner_ty);
            let buf = ensure_cpp_buf(ctx, names, tfm, source_deps);
            tfm.cpp.decl(&len_name, format!("{cpp_code}.size()"));
            add_ffi_arg(ast, ctx, tfm, source_deps, &len_name, &Usize);
            tfm.cpp.line(format!(
                "{cpp_helper}(std::move({cpp_code}), {});",
                buf.buf_name()
            ));
            source_deps.insert((SourceGroup::Anonymous, cpp_helper));
            let len_code = tfm.rust.find(&len_name, ty, RefInline).code;
            tfm.rust.decl(
                name,
                format!(
                    "{rust_helper}({len_code}, {}{})",
                    tfm.buf_ref,
                    buf.end_name()
                ),
            );
        }

        Optional(inner_ty) => {
            let cpp_code = tfm.cpp.find(name, ty, RefMany).code;
            let has_name = names.create(&format!("has_{name}"));
            let val_name = names.create(&format!("{name}_val"));
            ensure_cpp_buf(ctx, names, tfm, source_deps);

            tfm.cpp.decl(&has_name, format!("{cpp_code}.has_value()"));
            add_ffi_arg(ast, ctx, tfm, source_deps, &has_name, &Bool);

            let mut rust = FnBuilder::default();
            tfm.cpp.line(format!("if ({has_name}) {{"));
            tfm.cpp.pure_decl(&val_name, format!("{cpp_code}.value()"));
            {
                let old = tfm.buf_status;
                tfm.buf_status = BufStatus::Inside;
                std::mem::swap(&mut tfm.rust, &mut rust);
                transform_to_rust(ast, ctx, names, tfm, &val_name, inner_ty, source_deps);
                std::mem::swap(&mut tfm.rust, &mut rust);
                tfm.buf_status = old;
            }
            tfm.cpp.line("}".into());

            let has_code = tfm.rust.find(&has_name, ty, RefInline).code;
            let val_code = rust.find(&val_name, ty, RefInline).code;
            if rust.is_empty() {
                tfm.rust
                    .decl(name, format!("{has_code}.then(|| {val_code})"));
            } else {
                rust.insert_deferred_lines_here();
                rust.line(val_code);
                tfm.rust.line(format!("let {name} = {has_code}.then(|| {{"));
                tfm.rust.extend(rust);
                tfm.rust.line("});".to_string());
            }
        }

        Pair { .. } | Verbatim(_) | DynTrait(_) => unreachable!(),
    }
}

fn transform_to_cpp(
    ast: &AST,
    ctx: &mut CppCtx,
    names: &mut NameSet,
    tfm: &mut Transform,
    name: &str,
    ty: &RustType,
    source_deps: &mut HashSet<(SourceGroup, String)>,
) {
    use RustType::*;

    fn add_ffi_arg(
        ast: &AST,
        ctx: &mut CppCtx,
        tfm: &mut Transform,
        source_deps: &mut HashSet<(SourceGroup, String)>,
        name: &str,
        ty: &RustType,
    ) {
        match tfm.buf_status {
            BufStatus::Outside => tfm.ffi_args.push(RustArg {
                name: name.to_string(),
                ty: ty.clone(),
            }),
            BufStatus::Inside => {
                let buf = tfm.buf.as_ref().unwrap();

                // Rust (write)
                let code = tfm.rust.find(name, ty, RefInline).code;
                tfm.rust.line(format!(
                    "_ffi_write({code}, {}{});",
                    tfm.buf_ref,
                    buf.buf_name()
                ));
                ctx.rust_helpers.mark_used("_ffi_write");

                // C++ (read)
                let mut source = "_ffi_read<".to_string();
                CppTypeCtx {
                    cpp: &mut source,
                    ast,
                    deps: source_deps,
                    include_group: SourceGroup::Include,
                    decl_groups: None,
                    loc: TypeLoc::OutsideRustNamespace,
                    ns: &ctx.namespace,
                }
                .append_cpp_type(ty, CppDecl::Full);
                _ = write!(source, ">({})", buf.end_name());
                tfm.cpp.decl(name, source);
                source_deps.insert((SourceGroup::Anonymous, "_ffi_read".into()));
            }
        }
    }

    match ty {
        Bool | U8 | U16 | U32 | Usize | U64 | I8 | I16 | I32 | Isize | I64 | F32 | F64
        | ForeignHandle => add_ffi_arg(ast, ctx, tfm, source_deps, name, ty),

        RefStr | OwnStr => {
            let mut rust_code = tfm.rust.find(name, ty, RefInline).code;
            let ptr_name = names.create(&format!("{name}_ptr"));
            let len_name = names.create(&format!("{name}_len"));
            let cap_name = names.create(&format!("{name}_cap"));
            let ptr_ty = Pair {
                rust: ForeignHandle.into(),
                other: Verbatim("const char*".into()).into(),
            };
            if let RefStr = ty {
                rust_code.push_str(".into()");
            }
            tfm.rust.line(format!(
                "let ({ptr_name}, {len_name}, {cap_name}) = _ffi_string_to_host({rust_code});"
            ));
            ctx.rust_helpers.mark_used("_ffi_string_to_host");
            add_ffi_arg(ast, ctx, tfm, source_deps, &ptr_name, &ptr_ty);
            add_ffi_arg(ast, ctx, tfm, source_deps, &len_name, &Usize);
            add_ffi_arg(ast, ctx, tfm, source_deps, &cap_name, &Usize);
            tfm.cpp.decl(
                name,
                format!("_ffi_string_from_rust({ptr_name}, {len_name}, {cap_name})"),
            );
            source_deps.insert((SourceGroup::Anonymous, "_ffi_string_from_rust".into()));
        }

        Enum(enum_index) => {
            let rust = tfm.rust.find(name, ty, RefInline);
            let e = &ast.enums[*enum_index];
            if !e.has_fields() {
                let raw_name = names.create(&format!("{name}_raw"));
                tfm.rust
                    .maybe_pure_decl(rust.pure, &raw_name, format!("{} as i32", rust.code));
                add_ffi_arg(ast, ctx, tfm, source_deps, &raw_name, &I32);
                tfm.cpp
                    .decl(name, format!("{}::{}({raw_name})", ctx.namespace, e.name));
            } else {
                let (cpp_helper, rust_helper) = enum_to_cpp_helper(ast, ctx, *enum_index);
                let buf = ensure_rust_buf(ctx, names, tfm, source_deps);
                tfm.rust.line(format!(
                    "{rust_helper}({}, {}{});",
                    rust.code,
                    tfm.buf_ref,
                    buf.buf_name()
                ));
                tfm.cpp
                    .decl(name, format!("{cpp_helper}({})", buf.end_name()));
                source_deps.insert((SourceGroup::Anonymous, cpp_helper));
            }
        }

        Struct(struct_index) => {
            let rust = tfm.rust.find(name, ty, RefMany);
            let s = &ast.structs[*struct_index];
            let mut item_args = Vec::new();
            for f in &s.fields {
                let item_name = names.create(&format!("{name}_{}", f.name));
                tfm.rust.maybe_pure_decl(
                    rust.pure,
                    &item_name,
                    format!("{}.{}", rust.code, f.name),
                );
                transform_to_cpp(ast, ctx, names, tfm, &item_name, &f.ty, source_deps);
                item_args.push(RustArg {
                    name: item_name,
                    ty: f.ty.clone(),
                });
            }
            if s.fields.is_empty() {
                // Avoid an unused variable warning in Rust
                let code = tfm.rust.find(name, ty, RefInline).code;
                tfm.rust.line(format!("_ = {code};"));
            }
            let fields = tfm.cpp.find_args(&item_args, RefStdMove);
            tfm.cpp
                .decl(name, format!("{}::{}{{{fields}}}", ctx.namespace, s.name));
        }

        Tuple(types) => {
            let rust = tfm.rust.find(name, ty, RefMany);
            let mut item_args = Vec::new();
            for (i, item_ty) in types.iter().enumerate() {
                let item_name = names.create(&format!("{name}_{i}"));
                tfm.rust
                    .maybe_pure_decl(rust.pure, &item_name, format!("{}.{i}", rust.code));
                transform_to_cpp(ast, ctx, names, tfm, &item_name, &item_ty, source_deps);
                item_args.push(RustArg {
                    name: item_name,
                    ty: item_ty.clone(),
                });
            }
            if types.is_empty() {
                tfm.cpp.decl(name, "std::tuple<>()".to_string());

                // Avoid an unused variable warning in Rust
                let code = tfm.rust.find(name, ty, RefInline).code;
                tfm.rust.line(format!("_ = {code};"));
            } else {
                let cpp_code = tfm.cpp.find_args(&item_args, RefStdMove);
                tfm.cpp.decl(
                    name,
                    match types.len() {
                        1 => cpp_code,
                        _ => format!("std::make_tuple({cpp_code})"),
                    },
                );
            }
        }

        Ptr(kind, inner_ty) => {
            if let DynTrait(trait_index) = &**inner_ty {
                let rust_code = tfm.rust.find(name, ty, RefInline).code;
                let ptr_name = names.create(&format!("{name}_ptr"));
                let cpp_helper = trait_to_cpp_helper(ast, ctx, *trait_index, *kind);
                tfm.rust.decl(
                    &ptr_name,
                    format!("Box::into_raw(Box::new({rust_code})) as *const u8"),
                );
                add_ffi_arg(ast, ctx, tfm, source_deps, &ptr_name, &ForeignHandle);
                tfm.cpp.decl(
                    name,
                    match kind {
                        RustPtr::Box => {
                            let mut cpp_type = String::new();
                            CppTypeCtx {
                                cpp: &mut cpp_type,
                                ast,
                                deps: source_deps,
                                include_group: SourceGroup::Include,
                                decl_groups: None,
                                loc: TypeLoc::OutsideRustNamespace,
                                ns: &ctx.namespace,
                            }
                            .append_cpp_type(inner_ty, CppDecl::Forward);
                            format!("std::unique_ptr<{cpp_type}>(new {cpp_helper}({ptr_name}))")
                        }
                        RustPtr::Rc => format!("std::make_shared<{cpp_helper}>({ptr_name})"),
                    },
                );
            } else if *kind == RustPtr::Box {
                let rust_code = tfm.rust.find(name, ty, RefMany).code;
                let (cpp_helper, rust_helper) = box_to_cpp_helper(ast, ctx, inner_ty);
                let buf = ensure_rust_buf(ctx, names, tfm, source_deps);
                tfm.rust.line(format!(
                    "{rust_helper}(*{rust_code}, {}{});",
                    tfm.buf_ref,
                    buf.buf_name()
                ));
                tfm.cpp
                    .decl(name, format!("{cpp_helper}({})", buf.end_name()));
                source_deps.insert((SourceGroup::Anonymous, cpp_helper));
            } else {
                unreachable!()
            }
        }

        Vector(inner_ty) => {
            let rust_code = tfm.rust.find(name, ty, RefMany).code;
            let len_name = names.create(&format!("{name}_len"));
            let (cpp_helper, rust_helper) = vec_to_cpp_helper(ast, ctx, inner_ty);
            let buf = ensure_rust_buf(ctx, names, tfm, source_deps);
            tfm.rust.decl(&len_name, format!("{rust_code}.len()"));
            add_ffi_arg(ast, ctx, tfm, source_deps, &len_name, &Usize);
            tfm.rust.line(format!(
                "{rust_helper}({rust_code}, {}{});",
                tfm.buf_ref,
                buf.buf_name()
            ));
            let len_code = tfm.cpp.find(&len_name, ty, RefMany).code;
            tfm.cpp.decl(
                name,
                format!("{cpp_helper}({len_code}, {})", buf.end_name()),
            );
            source_deps.insert((SourceGroup::Anonymous, cpp_helper));
        }

        Optional(inner_ty) => {
            let rust_code = tfm.rust.find(name, ty, RefMany).code;
            let has_name = names.create(&format!("has_{name}"));
            let val_name = names.create(&format!("{name}_val"));
            ensure_rust_buf(ctx, names, tfm, source_deps);

            tfm.rust.decl(&has_name, format!("{rust_code}.is_some()"));
            add_ffi_arg(ast, ctx, tfm, source_deps, &has_name, &Bool);

            let mut cpp = FnBuilder::default();
            tfm.rust
                .line(format!("if let Some({val_name}) = {rust_code} {{"));
            {
                let old = tfm.buf_status;
                tfm.buf_status = BufStatus::Inside;
                std::mem::swap(&mut tfm.cpp, &mut cpp);
                transform_to_cpp(ast, ctx, names, tfm, &val_name, inner_ty, source_deps);
                std::mem::swap(&mut tfm.cpp, &mut cpp);
                tfm.buf_status = old;
            }
            tfm.rust.line("}".into());

            let has_code = tfm.cpp.find(&has_name, ty, RefInline).code;
            let mut val_code = cpp.find(&val_name, ty, RefInline).code;
            val_code = format!("std::make_optional({val_code})");
            if cpp.is_empty() {
                tfm.cpp
                    .decl(name, format!("{has_code} ? {val_code} : std::nullopt"));
            } else {
                let mut cpp_ty = String::new();
                CppTypeCtx {
                    cpp: &mut cpp_ty,
                    ast,
                    deps: source_deps,
                    include_group: SourceGroup::Include,
                    decl_groups: None,
                    loc: TypeLoc::OutsideRustNamespace,
                    ns: &ctx.namespace,
                }
                .append_cpp_type(ty, CppDecl::Full);
                cpp.insert_deferred_lines_here();
                cpp.line(format!("{name} = {val_code};"));
                tfm.cpp.line(format!("{cpp_ty} {name};"));
                tfm.cpp.line(format!("if ({has_code}) {{"));
                tfm.cpp.extend(cpp);
                tfm.cpp.line("}".to_string());
            }
        }

        Pair { .. } | Verbatim(_) | DynTrait(_) => unreachable!(),
    }
}

fn ensure_cpp_buf(
    ctx: &mut CppCtx,
    names: &mut NameSet,
    tfm: &mut Transform,
    source_deps: &mut HashSet<(SourceGroup, String)>,
) -> Rc<SharedBuf> {
    if let Some(buf) = &tfm.buf {
        return buf.clone();
    }

    let buf_name = names.create("buf");
    let ptr_name = names.create("buf_ptr");
    let end_name = names.create("buf_end");
    let buf = SharedBuf::new(&buf_name, &end_name);

    // C++ (write)
    tfm.cpp.line(format!("std::vector<uint8_t> {buf_name};"));
    tfm.cpp
        .defer_decl(&ptr_name, format!("_ffi_vec_to_rust({buf_name})"));
    source_deps.insert((SourceGroup::Anonymous, "_ffi_vec_to_rust".into()));

    // Rust (read)
    tfm.rust.line_alt(
        // Avoid a warning about an unnecessarily mutable variable
        format!("let {end_name} = {ptr_name};"),
        format!("let mut {end_name} = {ptr_name};"),
        buf.is_buf_name_used_flag(),
    );
    tfm.rust
        .defer_line(format!("_ffi_buf_from_host({ptr_name}, {end_name});"));
    ctx.rust_helpers.mark_used("_ffi_buf_from_host");

    // FFI
    tfm.buf = Some(buf.clone());
    tfm.buf_ref = "&mut ";
    tfm.ffi_args.push(RustArg {
        name: ptr_name,
        ty: RustType::ForeignHandle,
    });
    buf
}

fn ensure_rust_buf(
    ctx: &mut CppCtx,
    names: &mut NameSet,
    tfm: &mut Transform,
    source_deps: &mut HashSet<(SourceGroup, String)>,
) -> Rc<SharedBuf> {
    if let Some(buf) = &tfm.buf {
        return buf.clone();
    }

    let buf_name = names.create("buf");
    let ptr_name = names.create("buf_ptr");
    let end_name = names.create("buf_end");
    let cap_name = names.create("buf_cap");
    let buf = SharedBuf::new(&buf_name, &end_name);

    // Rust (write)
    tfm.rust.line_alt(
        // Avoid a warning about an unnecessarily mutable variable
        format!("let {buf_name} = Vec::<u8>::new();"),
        format!("let mut {buf_name} = Vec::<u8>::new();"),
        buf.is_buf_name_used_flag(),
    );
    tfm.rust.defer_line(format!(
        "let ({ptr_name}, {cap_name}) = _ffi_buf_to_host({buf_name});"
    ));
    ctx.rust_helpers.mark_used("_ffi_buf_to_host");

    // C++ (read)
    tfm.cpp.line_alt(
        "".to_string(),
        format!("auto {end_name} = (const uint8_t*){ptr_name};"),
        buf.is_end_name_used_flag(),
    );
    tfm.cpp
        .defer_line(format!("_ffi_dealloc({ptr_name}, {cap_name});"));
    source_deps.insert((SourceGroup::ExternCDecl, "_ffi_dealloc".into()));

    // FFI
    tfm.buf = Some(buf.clone());
    tfm.buf_ref = "&mut ";
    tfm.ffi_args.push(RustArg {
        name: ptr_name,
        ty: RustType::ForeignHandle,
    });
    tfm.ffi_args.push(RustArg {
        name: cap_name,
        ty: RustType::Usize,
    });
    buf
}

fn vec_to_rust_helper(ast: &AST, ctx: &mut CppCtx, inner_ty: &RustType) -> (String, String) {
    if let Some(result) = ctx.vec_to_rust_helpers.get(inner_ty) {
        return result.clone();
    }

    let mut base_name = "_ffi_vec_".to_string();
    append_type_name_hint(&mut base_name, ast, inner_ty);
    let cpp_name = ctx.helper_names.create(&format!("{base_name}_to_rust"));
    let rust_name = ctx.helper_names.create(&format!("{base_name}_from_cpp"));
    let cpp_name_decl = format!("{cpp_name}[decl]");

    // This must be done first to avoid a stack overflow
    ctx.vec_to_rust_helpers
        .insert(inner_ty.clone(), (cpp_name.clone(), rust_name.clone()));

    let mut locals = NameSet::default();
    let vec_name = locals.create("items");
    let item_name = locals.create("item");
    let end_name = locals.create("end");
    let len_name = locals.create("len");
    let buf_name = locals.create("buf");

    // Transform the items
    let mut tfm = Transform::default();
    let mut source_deps = HashSet::new();
    let buf = SharedBuf::new(&buf_name, &end_name);
    tfm.buf = Some(buf.clone());
    tfm.buf_status = BufStatus::Inside;
    tfm.cpp.mark_pure(&item_name);
    transform_to_rust(
        ast,
        ctx,
        &mut locals,
        &mut tfm,
        &item_name,
        &inner_ty,
        &mut source_deps,
    );
    let item_code = tfm.rust.find(&item_name, inner_ty, RefInline).code;
    tfm.rust.line(format!("{vec_name}.push({item_code});"));

    // Source (forward declaration)
    let mut cpp_ty = String::new();
    {
        let mut source_deps = HashSet::new();
        CppTypeCtx {
            cpp: &mut cpp_ty,
            ast,
            deps: &mut source_deps,
            include_group: SourceGroup::Include,
            decl_groups: None,
            loc: TypeLoc::OutsideRustNamespace,
            ns: &ctx.namespace,
        }
        .append_cpp_type(inner_ty, CppDecl::Full);
        let source = format!(
            "\nvoid {cpp_name}(std::vector<{cpp_ty}>&& {vec_name}, std::vector<uint8_t>& {buf_name});\n"
        );
        ctx.source_helpers
            .add_group(SourceGroup::Anonymous, &cpp_name_decl, source)
            .set_is_forward_decl();
    }

    // Source
    {
        let mut source = format!(
            "\nvoid {cpp_name}(std::vector<{cpp_ty}>&& {vec_name}, std::vector<uint8_t>& {buf_name}) {{\n"
        );
        if !tfm.cpp.is_empty() {
            _ = write!(source, "    for (auto&& {item_name} : {vec_name}) {{\n");
            tfm.cpp
                .write_to_cpp(ctx, ast, &mut source_deps, &mut source, "        ");
            source.push_str("    }\n");
        }
        source.push_str("}\n");
        ctx.source_helpers
            .add_group(SourceGroup::Anonymous, &cpp_name, source)
            .add_forward_decl_group(SourceGroup::Anonymous, &cpp_name_decl)
            .add_deps_group(source_deps);
    }

    // Rust
    {
        let mut rust = String::new();
        let mut item_ty = String::new();
        let end_name = buf.final_end_name_for_rust();
        append_rust_type(&mut item_ty, ast, inner_ty);
        allow_non_snake_case(&mut rust, &rust_name);
        _ = write!(
            rust,
            "\nfn {rust_name}({len_name}: usize, {end_name}: &mut *const u8) -> Vec<{item_ty}> {{\n"
        );
        _ = write!(
            rust,
            "    let mut {vec_name} = Vec::<{item_ty}>::with_capacity({len_name});\n"
        );
        _ = write!(rust, "    for _ in 0..{len_name} {{\n");
        tfm.rust.write_to_rust(ast, &mut rust, "        ");
        rust.push_str("    }\n");
        _ = write!(rust, "    {vec_name}\n");
        rust.push_str("}\n");
        ctx.rust_helpers.add(&rust_name, rust).mark_used();
    }

    (cpp_name, rust_name)
}

fn vec_to_cpp_helper(ast: &AST, ctx: &mut CppCtx, inner_ty: &RustType) -> (String, String) {
    if let Some(result) = ctx.vec_to_cpp_helpers.get(inner_ty) {
        return result.clone();
    }

    let mut base_name = "_ffi_vec_".to_string();
    append_type_name_hint(&mut base_name, ast, inner_ty);
    let cpp_name = ctx.helper_names.create(&format!("{base_name}_from_rust"));
    let rust_name = ctx.helper_names.create(&format!("{base_name}_to_cpp"));
    let cpp_name_decl = format!("{cpp_name}[decl]");

    // This must be done first to avoid a stack overflow
    ctx.vec_to_cpp_helpers
        .insert(inner_ty.clone(), (cpp_name.clone(), rust_name.clone()));

    let mut locals = NameSet::default();
    let vec_name = locals.create("items");
    let item_name = locals.create("item");
    let end_name = locals.create("end");
    let len_name = locals.create("len");
    let buf_name = locals.create("buf");

    // Transform the items
    let mut tfm = Transform::default();
    let mut source_deps = HashSet::new();
    let buf = SharedBuf::new(&buf_name, &end_name);
    tfm.buf = Some(buf.clone());
    tfm.buf_status = BufStatus::Inside;
    tfm.rust.mark_pure(&item_name);
    transform_to_cpp(
        ast,
        ctx,
        &mut locals,
        &mut tfm,
        &item_name,
        &inner_ty,
        &mut source_deps,
    );
    let item_code = tfm.cpp.find(&item_name, inner_ty, RefStdMove).code;
    tfm.cpp
        .line(format!("{vec_name}.emplace_back({item_code});"));

    // Rust
    {
        let mut rust = String::new();
        let buf_name = buf.final_buf_name_for_rust();
        allow_non_snake_case(&mut rust, &rust_name);
        _ = write!(rust, "\nfn {rust_name}({vec_name}: Vec<");
        append_rust_type(&mut rust, ast, inner_ty);
        _ = write!(rust, ">, {buf_name}: &mut Vec<u8>) {{\n");
        if !tfm.rust.is_empty() {
            _ = write!(rust, "    for {item_name} in {vec_name} {{\n");
            tfm.rust.write_to_rust(ast, &mut rust, "        ");
            rust.push_str("    }\n");
        }
        rust.push_str("}\n");
        ctx.rust_helpers.add(&rust_name, rust).mark_used();
    }

    // Source (forward declaration)
    let mut cpp_ty = String::new();
    {
        let mut source_deps = HashSet::new();
        CppTypeCtx {
            cpp: &mut cpp_ty,
            ast,
            deps: &mut source_deps,
            include_group: SourceGroup::Include,
            decl_groups: None,
            loc: TypeLoc::OutsideRustNamespace,
            ns: &ctx.namespace,
        }
        .append_cpp_type(inner_ty, CppDecl::Full);
        let source = format!(
            "\nstd::vector<{cpp_ty}> {cpp_name}(uintptr_t {len_name}, const uint8_t*& {end_name});\n"
        );
        ctx.source_helpers
            .add_group(SourceGroup::Anonymous, &cpp_name_decl, source)
            .set_is_forward_decl();
    }

    // Source
    {
        let mut source = String::new();
        _ = write!(
            source,
            "
std::vector<{cpp_ty}> {cpp_name}(uintptr_t {len_name}, const uint8_t*& {end_name}) {{
    std::vector<{cpp_ty}> {vec_name};
    {vec_name}.reserve({len_name});
    while ({vec_name}.size() < {len_name}) {{
"
        );
        tfm.cpp
            .write_to_cpp(ctx, ast, &mut source_deps, &mut source, "        ");
        source.push_str("    }\n");
        _ = write!(source, "    return {vec_name};\n");
        source.push_str("}\n");
        ctx.source_helpers
            .add_group(SourceGroup::Anonymous, &cpp_name, source)
            .add_forward_decl_group(SourceGroup::Anonymous, &cpp_name_decl)
            .add_deps_group(source_deps);
    }

    (cpp_name, rust_name)
}

fn trait_to_rust_helper(ast: &AST, ctx: &mut CppCtx, trait_index: usize, kind: RustPtr) -> String {
    if let Some(result) = ctx.trait_to_rust_helpers.get(&(kind, trait_index)) {
        return result.clone();
    }

    let t = &ast.traits[trait_index];
    let rust_name = format!("_ffi_rs_{kind:?}_{}", t.name);
    let drop_name = format!("_ffi_cpp_drop_{kind:?}_{}", t.name);

    // This must be done first to avoid a stack overflow
    ctx.trait_to_rust_helpers
        .insert((kind, trait_index), rust_name.clone());

    // Source: ExternCImpl
    {
        let mut source = String::new();
        let mut source_deps = HashSet::new();
        source.push('\n');
        CppTypeCtx {
            cpp: &mut source,
            ast,
            deps: &mut source_deps,
            include_group: SourceGroup::Include,
            decl_groups: None,
            loc: TypeLoc::OutsideRustNamespace,
            ns: &ctx.namespace,
        }
        .append_cpp_signature(
            None,
            &drop_name,
            None,
            &[RustArg {
                name: "self".to_string(),
                ty: TraitInfo { t, kind }.self_type(&ctx.namespace),
            }],
        );
        source.push_str(" {\n");
        source.push_str("    delete self;\n");
        source.push_str("}\n");
        ctx.source_helpers
            .add_group(SourceGroup::ExternCImpl, &drop_name, source)
            .add_deps_group(source_deps)
            .mark_used();
    }

    // Rust
    {
        let mut rust = String::new();
        allow_non_camel_case_types(&mut rust, &rust_name);
        _ = write!(rust, "\nstruct {rust_name}(*const u8);\n");
        _ = write!(rust, "\nimpl Drop for {rust_name} {{\n");
        rust.push_str("    fn drop(&mut self) {\n");
        _ = write!(
            rust,
            "        {} \"C\" {{ fn {drop_name}(_: *const u8); }}\n",
            ctx.syntax.unsafe_extern()
        );
        _ = write!(rust, "        unsafe {{ {drop_name}(self.0) }};\n");
        rust.push_str("    }\n");
        rust.push_str("}\n");
        _ = write!(rust, "\nimpl {} for {rust_name} {{", t.name);
        for f in &t.fns {
            generate_rust_to_cpp_fn(ast, ctx, kind, t, f, &mut rust);
        }
        rust.push_str("}\n");
        ctx.rust_helpers.add(&rust_name, rust).mark_used();
    }

    rust_name
}

fn trait_to_cpp_helper(ast: &AST, ctx: &mut CppCtx, trait_index: usize, kind: RustPtr) -> String {
    if let Some(result) = ctx.trait_to_cpp_helpers.get(&(kind, trait_index)) {
        return result.clone();
    }

    let t = &ast.traits[trait_index];
    let drop_name = format!("_ffi_drop_{kind:?}_{}", t.name);
    let cpp_name = TraitInfo { t, kind }.cpp_name();

    // This must be done first to avoid a stack overflow
    ctx.trait_to_cpp_helpers
        .insert((kind, trait_index), cpp_name.clone());

    // Source: ExternCDecl
    {
        let mut source = String::new();
        let mut source_deps = HashSet::new();
        CppTypeCtx {
            cpp: &mut source,
            ast,
            deps: &mut source_deps,
            include_group: SourceGroup::Include,
            decl_groups: None,
            loc: TypeLoc::OutsideRustNamespace,
            ns: &ctx.namespace,
        }
        .append_cpp_signature(
            None,
            &drop_name,
            None,
            &[RustArg {
                name: "ptr".to_string(),
                ty: RustType::ForeignHandle,
            }],
        );
        source.push_str(";\n");
        ctx.source_helpers
            .add_group(SourceGroup::ExternCDecl, &drop_name, source)
            .add_deps_group(source_deps);
    }

    // Source: Anonymous
    {
        let mut source = String::new();
        _ = write!(
            source,
            "\nstruct {cpp_name} final : {}::{} {{\n",
            ctx.namespace, t.name
        );
        _ = write!(
            source,
            "    {cpp_name}(const void* ptr) : _self(ptr) {{}}\n"
        );
        _ = write!(
            source,
            "    virtual ~{cpp_name}() {{ {drop_name}(_self); }}\n"
        );
        for f in &t.fns {
            let info = Some(TraitInfo { t, kind });
            source.push_str("    virtual ");
            generate_cpp_to_rust_fn(ast, ctx, f, &mut source, info);
        }
        source.push_str("    const void* _self;\n");
        source.push_str("};\n");
        ctx.source_helpers
            .add_group(SourceGroup::Anonymous, &cpp_name, source)
            .add_dep_group(SourceGroup::ExternCDecl, &drop_name)
            .mark_used();
    }

    // Rust
    {
        let mut rust = String::new();
        _ = write!(rust, "\n{}\n", ctx.syntax.unsafe_no_mangle());
        _ = write!(rust, "extern \"C\" fn {drop_name}(ptr: *const u8) {{\n");
        _ = write!(
            rust,
            "    drop(unsafe {{ Box::from_raw(ptr as *mut {}<dyn {}>) }});\n",
            kind.path(),
            t.name
        );
        rust.push_str("}\n");
        ctx.rust_helpers.add(&drop_name, rust).mark_used();
    }

    cpp_name
}

fn box_to_rust_helper(ast: &AST, ctx: &mut CppCtx, inner_ty: &RustType) -> (String, String) {
    if let Some(result) = ctx.box_to_rust_helpers.get(inner_ty) {
        return result.clone();
    }

    let mut base_name = "_ffi_box_".to_string();
    append_type_name_hint(&mut base_name, ast, inner_ty);
    let cpp_name = ctx.helper_names.create(&format!("{base_name}_to_rust"));
    let rust_name = ctx.helper_names.create(&format!("{base_name}_from_cpp"));
    let cpp_name_decl = format!("{cpp_name}[decl]");

    // This must be done first to avoid a stack overflow
    ctx.box_to_rust_helpers
        .insert(inner_ty.clone(), (cpp_name.clone(), rust_name.clone()));

    let mut locals = NameSet::default();
    let val_name = locals.create("val");
    let end_name = locals.create("end");
    let buf_name = locals.create("buf");

    // Transform the value
    let mut tfm = Transform::default();
    let mut source_deps = HashSet::new();
    let buf = SharedBuf::new(&buf_name, &end_name);
    tfm.buf = Some(buf.clone());
    tfm.buf_status = BufStatus::Inside;
    tfm.cpp.mark_pure(&val_name);
    transform_to_rust(
        ast,
        ctx,
        &mut locals,
        &mut tfm,
        &val_name,
        &inner_ty,
        &mut source_deps,
    );
    let val_code = tfm.rust.find(&val_name, inner_ty, RefInline).code;
    tfm.rust.line(format!("Box::new({val_code})"));

    // Source (forward declaration)
    let mut cpp_ty = String::new();
    {
        CppTypeCtx {
            cpp: &mut cpp_ty,
            ast,
            deps: &mut source_deps,
            include_group: SourceGroup::Include,
            decl_groups: None,
            loc: TypeLoc::OutsideRustNamespace,
            ns: &ctx.namespace,
        }
        .append_cpp_type(inner_ty, CppDecl::Full);
        ctx.source_helpers
            .add_group(
                SourceGroup::Anonymous,
                &cpp_name_decl,
                format!(
                    "\nvoid {cpp_name}({cpp_ty} {val_name}, std::vector<uint8_t>& {buf_name});\n"
                ),
            )
            .set_is_forward_decl();
    }

    // Source
    {
        let mut source = String::new();
        _ = write!(
            source,
            "\nvoid {cpp_name}({cpp_ty} {val_name}, std::vector<uint8_t>& {buf_name}) {{\n"
        );
        tfm.cpp
            .write_to_cpp(ctx, ast, &mut source_deps, &mut source, "    ");
        source.push_str("}\n");
        ctx.source_helpers
            .add_group(SourceGroup::Anonymous, &cpp_name, source)
            .add_forward_decl_group(SourceGroup::Anonymous, &cpp_name_decl)
            .add_deps_group(source_deps);
    }

    // Rust
    {
        let mut rust = String::new();
        let mut item_ty = String::new();
        let end_name = buf.final_end_name_for_rust();
        append_rust_type(&mut item_ty, ast, inner_ty);
        allow_non_snake_case(&mut rust, &rust_name);
        _ = write!(
            rust,
            "\nfn {rust_name}({end_name}: &mut *const u8) -> Box<{item_ty}> {{\n"
        );
        tfm.rust.write_to_rust(ast, &mut rust, "    ");
        rust.push_str("}\n");
        ctx.rust_helpers.add(&rust_name, rust).mark_used();
    }

    (cpp_name, rust_name)
}

fn box_to_cpp_helper(ast: &AST, ctx: &mut CppCtx, inner_ty: &RustType) -> (String, String) {
    if let Some(result) = ctx.box_to_cpp_helpers.get(inner_ty) {
        return result.clone();
    }

    let mut base_name = "_ffi_box_".to_string();
    append_type_name_hint(&mut base_name, ast, inner_ty);
    let cpp_name = ctx.helper_names.create(&format!("{base_name}_from_rust"));
    let rust_name = ctx.helper_names.create(&format!("{base_name}_to_cpp"));
    let cpp_name_decl = format!("{cpp_name}[decl]");

    // This must be done first to avoid a stack overflow
    ctx.box_to_cpp_helpers
        .insert(inner_ty.clone(), (cpp_name.clone(), rust_name.clone()));

    let mut locals = NameSet::default();
    let val_name = locals.create("val");
    let end_name = locals.create("end");
    let buf_name = locals.create("buf");

    // Transform the items
    let mut tfm = Transform::default();
    let mut source_deps = HashSet::new();
    let buf = SharedBuf::new(&buf_name, &end_name);
    tfm.buf = Some(buf.clone());
    tfm.buf_status = BufStatus::Inside;
    tfm.rust.mark_pure(&val_name);
    transform_to_cpp(
        ast,
        ctx,
        &mut locals,
        &mut tfm,
        &val_name,
        &inner_ty,
        &mut source_deps,
    );
    let val_code = tfm.cpp.find(&val_name, inner_ty, RefStdMove).code;

    // Rust
    {
        let mut rust = String::new();
        let buf_name = buf.final_buf_name_for_rust();
        allow_non_snake_case(&mut rust, &rust_name);
        _ = write!(rust, "\nfn {rust_name}({val_name}: ");
        append_rust_type(&mut rust, ast, inner_ty);
        _ = write!(rust, ", {buf_name}: &mut Vec<u8>) {{\n");
        tfm.rust.write_to_rust(ast, &mut rust, "    ");
        rust.push_str("}\n");
        ctx.rust_helpers.add(&rust_name, rust).mark_used();
    }

    // Source (forward declaration)
    let mut cpp_ty = String::new();
    {
        CppTypeCtx {
            cpp: &mut cpp_ty,
            ast,
            deps: &mut source_deps,
            include_group: SourceGroup::Include,
            decl_groups: None,
            loc: TypeLoc::OutsideRustNamespace,
            ns: &ctx.namespace,
        }
        .append_cpp_type(inner_ty, CppDecl::Full);
        ctx.source_helpers
            .add_group(
                SourceGroup::Anonymous,
                &cpp_name_decl,
                format!("\nstd::unique_ptr<{cpp_ty}> {cpp_name}(const uint8_t*& {end_name});\n"),
            )
            .set_is_forward_decl();
    }

    // Source
    {
        let mut source = String::new();
        _ = write!(
            source,
            "\nstd::unique_ptr<{cpp_ty}> {cpp_name}(const uint8_t*& {end_name}) {{\n"
        );
        tfm.cpp
            .write_to_cpp(ctx, ast, &mut source_deps, &mut source, "    ");
        _ = write!(
            source,
            "    return std::make_unique<{cpp_ty}>({val_code});\n"
        );
        source.push_str("}\n");
        ctx.source_helpers
            .add_group(SourceGroup::Anonymous, &cpp_name, source)
            .add_forward_decl_group(SourceGroup::Anonymous, &cpp_name_decl)
            .add_deps_group(source_deps);
    }

    (cpp_name, rust_name)
}

fn enum_to_rust_helper(ast: &AST, ctx: &mut CppCtx, enum_index: usize) -> (String, String) {
    if let Some(result) = ctx.enum_to_rust_helpers.get(&enum_index) {
        return result.clone();
    }

    let e = &ast.enums[enum_index];
    let base_name = format!("_ffi_enum_{}", e.name);
    let rust_name = ctx.helper_names.create(&format!("{base_name}_from_cpp"));
    let cpp_name = ctx.helper_names.create(&format!("{base_name}_to_rust"));
    let cpp_name_decl = format!("{cpp_name}[decl]");

    // This must be done first to avoid a stack overflow
    ctx.enum_to_rust_helpers
        .insert(enum_index, (cpp_name.clone(), rust_name.clone()));

    let mut locals = NameSet::default();
    let val_name = locals.create("val");
    let buf_name = locals.create("buf");
    let end_name = locals.create("end");
    let it_name = locals.create("it");
    let mut branches = Vec::new();
    let mut source_deps = HashSet::new();

    // Enums without fields are just integers
    if !e.has_fields() {
        let mut rust = String::new();
        allow_non_snake_case(&mut rust, &rust_name);
        _ = write!(rust, "\nfn {rust_name}({val_name}: i32) -> {} {{\n", e.name);
        _ = write!(rust, "    match {val_name} {{\n");
        for v in &e.variants {
            _ = write!(
                rust,
                "        {} => {}::{},\n",
                v.discriminant, e.name, v.name
            );
        }
        rust.push_str("        _ => panic!(),\n");
        rust.push_str("    }\n");
        rust.push_str("}\n");
        ctx.rust_helpers.add(&rust_name, rust).mark_used();
        return (cpp_name, rust_name);
    }

    struct Branch {
        tfm: Transform,
        fields: Vec<String>,
    }

    // Transform all fields for each variant in a separate branch
    for v in &e.variants {
        let mut branch_locals = locals.clone();
        let mut fields = Vec::new();
        let mut tfm = Transform::default();
        let buf = SharedBuf::new(&buf_name, &end_name);
        tfm.buf = Some(buf.clone());
        tfm.buf_status = BufStatus::Inside;
        for f in &v.fields {
            let field_name = branch_locals.create(&name_for_match(&f.name, v.fields.len()));
            tfm.cpp.pure_decl(
                &field_name,
                format!("{it_name}->{}", with_digit_prefix(&f.name)),
            );
            transform_to_rust(
                ast,
                ctx,
                &mut branch_locals,
                &mut tfm,
                &field_name,
                &f.ty,
                &mut source_deps,
            );
            fields.push(field_name);
        }
        rust_decl_ctor(
            &mut tfm.rust,
            &val_name,
            &format!("{}::{}", e.name, v.name),
            &v.fields,
            fields.iter().map(|x| Cow::Borrowed(x.as_str())).collect(),
        );
        branches.push(Branch { tfm, fields });
    }

    // Source (forward declaration)
    {
        ctx.source_helpers
            .add_group(
                SourceGroup::Anonymous,
                &cpp_name_decl,
                format!(
                    "\nvoid {cpp_name}({}::{} {val_name}, std::vector<uint8_t>& {buf_name});\n",
                    ctx.namespace, e.name
                ),
            )
            .set_is_forward_decl();
    }

    // Source
    {
        let mut source = String::new();
        let mut is_first = true;
        _ = write!(
            source,
            "\nvoid {cpp_name}({}::{} {val_name}, std::vector<uint8_t>& {buf_name}) {{",
            ctx.namespace, e.name
        );
        for (v, branch) in e.variants.iter().zip(&mut branches) {
            source.push_str(if is_first { "\n    " } else { " else " });
            is_first = false;
            if branch.fields.is_empty() {
                _ = write!(
                    source,
                    "if ({val_name}.is<{}::{}::{}>()) {{\n",
                    ctx.namespace, e.name, v.name
                );
            } else {
                _ = write!(
                    source,
                    "if (auto {it_name} = {val_name}.as<{}::{}::{}>()) {{\n",
                    ctx.namespace, e.name, v.name
                );
            }
            _ = write!(
                source,
                "        _ffi_write(int32_t({}), {buf_name});\n",
                v.discriminant
            );
            source_deps.insert((SourceGroup::Anonymous, "_ffi_write".into()));
            branch
                .tfm
                .cpp
                .write_to_cpp(ctx, ast, &mut source_deps, &mut source, "        ");
            source.push_str("    }");
        }
        if is_first {
            source.push_str("    abort();\n");
        } else {
            source.push_str(" else {\n        abort();\n    }");
        }
        source_deps.insert((SourceGroup::Include, "<stdlib.h>".into())); // For "abort"
        source.push_str("\n}\n");
        ctx.source_helpers
            .add_group(SourceGroup::Anonymous, &cpp_name, source)
            .add_forward_decl_group(SourceGroup::Anonymous, &cpp_name_decl)
            .add_deps_group(source_deps)
            .mark_used();
    }

    // Rust
    {
        let mut rust = String::new();
        allow_non_snake_case(&mut rust, &rust_name);
        _ = write!(
            rust,
            "\nfn {rust_name}({end_name}: &mut *const u8) -> {} {{\n",
            e.name
        );
        _ = write!(rust, "    match _ffi_read::<i32>({end_name}) {{\n");
        for (v, branch) in e.variants.iter().zip(&mut branches) {
            let val_code = branch
                .tfm
                .rust
                .find(&val_name, &RustType::Enum(enum_index), RefInline)
                .code;
            if branch.tfm.rust.is_empty() {
                let val_code = format!("{} => {val_code},", v.discriminant);
                branch.tfm.rust.line(val_code);
                branch.tfm.rust.write_to_rust(ast, &mut rust, "        ");
            } else {
                _ = write!(rust, "        {} => {{", v.discriminant);
                branch.tfm.rust.line(val_code);
                branch
                    .tfm
                    .rust
                    .write_to_rust(ast, &mut rust, "            ");
                rust.push_str("        }\n");
            }
        }
        rust.push_str("        _ => panic!(),\n");
        rust.push_str("    }\n");
        rust.push_str("}\n");
        ctx.rust_helpers
            .add(&rust_name, rust)
            .add_dep("_ffi_read")
            .mark_used();
    }

    (cpp_name, rust_name)
}

fn enum_to_cpp_helper(ast: &AST, ctx: &mut CppCtx, enum_index: usize) -> (String, String) {
    if let Some(result) = ctx.enum_to_cpp_helpers.get(&enum_index) {
        return result.clone();
    }

    let e = &ast.enums[enum_index];
    let base_name = format!("_ffi_enum_{}", e.name);
    let cpp_name = ctx.helper_names.create(&format!("{base_name}_from_rust"));
    let rust_name = ctx.helper_names.create(&format!("{base_name}_to_cpp"));
    let cpp_name_decl = format!("{cpp_name}[decl]");

    // This must be done first to avoid a stack overflow
    ctx.enum_to_cpp_helpers
        .insert(enum_index, (cpp_name.clone(), rust_name.clone()));

    struct Branch {
        tfm: Transform,
        fields: Vec<String>,
    }

    let mut locals = NameSet::default();
    let val_name = locals.create("val");
    let buf_name = locals.create("buf");
    let end_name = locals.create("end");
    let mut branches = Vec::new();
    let mut source_deps = HashSet::new();

    // Transform all fields for each variant in a separate branch
    for v in &e.variants {
        let mut branch_locals = locals.clone();
        let mut fields = Vec::new();
        let mut tfm = Transform::default();
        let buf = SharedBuf::new(&buf_name, &end_name);
        tfm.buf = Some(buf.clone());
        tfm.buf_status = BufStatus::Inside;
        for f in &v.fields {
            let field_name = branch_locals.create(&name_for_match(&f.name, v.fields.len()));
            tfm.rust.mark_pure(&field_name);
            transform_to_cpp(
                ast,
                ctx,
                &mut branch_locals,
                &mut tfm,
                &field_name,
                &f.ty,
                &mut source_deps,
            );
            fields.push(field_name);
        }
        let args = tfm.cpp.find_args(
            &v.fields
                .iter()
                .zip(&fields)
                .map(|(f, name)| RustArg {
                    name: name.clone(),
                    ty: f.ty.clone(),
                })
                .collect(),
            RefStdMove,
        );
        tfm.cpp.decl(
            &val_name,
            format!(
                "{}::{}{{{}::{}::{}{{{args}}}}}",
                ctx.namespace, e.name, ctx.namespace, e.name, v.name
            ),
        );
        branches.push(Branch { tfm, fields });
    }

    // Rust
    {
        let mut rust = String::new();
        allow_non_snake_case(&mut rust, &rust_name);
        _ = write!(
            rust,
            "\nfn {rust_name}({val_name}: {}, {buf_name}: &mut Vec<u8>) {{\n",
            e.name
        );
        _ = write!(rust, "    match {val_name} {{\n");
        for (v, branch) in e.variants.iter().zip(&mut branches) {
            _ = write!(rust, "        {}::{}", e.name, v.name);
            if v.fields.iter().any(|f| starts_with_digit(&f.name)) {
                rust.push_str("(");
                for (i, name) in branch.fields.iter().enumerate() {
                    rust.push_str(if i > 0 { ", " } else { "" });
                    rust.push_str(name);
                }
                rust.push_str(")");
            } else if !v.fields.is_empty() {
                rust.push_str(" {");
                for (i, (f, name)) in v.fields.iter().zip(&branch.fields).enumerate() {
                    rust.push_str(if i > 0 { ", " } else { " " });
                    if f.name != *name {
                        _ = write!(rust, "{}: ", f.name);
                    }
                    rust.push_str(name);
                }
                rust.push_str(" }");
            }
            if branch.tfm.rust.is_empty() {
                _ = write!(
                    rust,
                    " => _ffi_write({} as i32, {buf_name}),\n",
                    v.discriminant
                );
            } else {
                rust.push_str(" => {\n");
                _ = write!(
                    rust,
                    "            _ffi_write({} as i32, {buf_name});\n",
                    v.discriminant
                );
                branch
                    .tfm
                    .rust
                    .write_to_rust(ast, &mut rust, "            ");
                rust.push_str("        }\n");
            }
        }
        rust.push_str("    }\n");
        rust.push_str("}\n");
        ctx.rust_helpers
            .add(&rust_name, rust)
            .add_dep("_ffi_write")
            .mark_used();
    }

    // Source (forward declaration)
    {
        ctx.source_helpers
            .add_group(
                SourceGroup::Anonymous,
                &cpp_name_decl,
                format!(
                    "\n{}::{} {cpp_name}(const uint8_t*& {end_name});\n",
                    ctx.namespace, e.name
                ),
            )
            .set_is_forward_decl();
    }

    // Source
    {
        let mut source = String::new();
        _ = write!(
            source,
            "\n{}::{} {cpp_name}(const uint8_t*& {end_name}) {{\n",
            ctx.namespace, e.name
        );
        _ = write!(source, "    switch (_ffi_read<int32_t>({end_name})) {{\n",);
        for (v, branch) in e.variants.iter().zip(&mut branches) {
            let val_code = branch
                .tfm
                .cpp
                .find(&val_name, &RustType::Enum(enum_index), RefInline)
                .code;
            let needs_block = !branch.tfm.cpp.is_empty();
            branch.tfm.cpp.line(format!("return {val_code};"));
            if needs_block {
                _ = write!(source, "    case {}: {{\n", v.discriminant);
            } else {
                _ = write!(source, "    case {}:\n", v.discriminant);
            }
            branch
                .tfm
                .cpp
                .write_to_cpp(ctx, ast, &mut source_deps, &mut source, "        ");
            if needs_block {
                source.push_str("    }\n");
            }
        }
        source.push_str("    default:\n        abort();\n");
        source_deps.insert((SourceGroup::Include, "<stdlib.h>".into())); // For "abort"
        source.push_str("    }\n");
        source.push_str("}\n");
        source_deps.insert((SourceGroup::Anonymous, "_ffi_read".into()));
        ctx.source_helpers
            .add_group(SourceGroup::Anonymous, &cpp_name, source)
            .add_forward_decl_group(SourceGroup::Anonymous, &cpp_name_decl)
            .add_deps_group(source_deps)
            .mark_used();
    }

    (cpp_name, rust_name)
}

fn multi_ret_helper(ast: &AST, ctx: &mut CppCtx, args: &[RustArg]) -> String {
    let types: Vec<_> = args.iter().map(|arg| arg.ty.clone()).collect();
    if let Some(result) = ctx.multi_ret_helpers.get(&types) {
        return result.clone();
    }

    let mut ty_name = "_ffi_ret_".to_string();
    append_type_name_hints(&mut ty_name, ast, &types);
    let ty_name = ctx.helper_names.create(&ty_name);

    // Source
    {
        let mut source = String::new();
        let mut source_deps = HashSet::new();
        _ = write!(source, "\nstruct {ty_name} {{\n");
        for (i, ty) in types.iter().enumerate() {
            source.push_str("    ");
            CppTypeCtx {
                cpp: &mut source,
                ast,
                deps: &mut source_deps,
                include_group: SourceGroup::Include,
                decl_groups: None,
                loc: TypeLoc::OutsideRustNamespace,
                ns: &ctx.namespace,
            }
            .append_cpp_type(ty, CppDecl::Full);
            _ = write!(source, " _{i};\n");
        }
        source.push_str("};\n");
        ctx.source_helpers
            .add_group(SourceGroup::MultiRet, &ty_name, source)
            .add_deps_group(source_deps)
            .mark_used();
    }

    // Rust
    {
        let mut rust = String::new();
        _ = write!(rust, "\n#[repr(C)]\nstruct {ty_name}(");
        for (i, ty) in types.iter().enumerate() {
            if i > 0 {
                rust.push_str(", ");
            }
            append_rust_type(&mut rust, ast, ty);
        }
        rust.push_str(");\n");
        ctx.rust_helpers.add(&ty_name, rust).mark_used();
    }

    ctx.multi_ret_helpers.insert(types, ty_name.clone());
    ty_name
}

// For something like "std::vector<Foo> foo;" C++ just needs a forward
// declaration. The reason is something like this: The member "foo" only holds
// a pointer to "Foo", so the compiler doesn't need detailed information about
// "Foo" such as its size and alignment. We use "CppDecl::Forward" to model
// this, which we switch to when we're inside of "std::vector".
//
// However, for something like "Foo foo;" C++ needs a full declaration. The
// reason is something like this: The member "foo" is stored inline, so the
// compiler needs detailed information about "Foo" such as its size and
// alignment. We use "CppDecl::Full" to model this, which we use for top-level
// struct member declarations.
//
// This distinction can matter for mutually-recursive types. Consider the
// following types "Foo" and "Bar":
//
//     struct Foo {
//          Bar bar;
//     };
//
//     struct Bar {
//          std::vector<Foo> foo;
//     };
//
// We can't compile this by picking a declaration order. We also can't compile
// this by having each one just depend on the forward declaration of the other,
// "Foo" actually depends on the full declaration of "Bar". The end result
// needs to at least have the following things, in order:
//
//     struct Foo;
//
//     struct Bar {
//          std::vector<Foo> foo;
//     };
//
//     struct Foo {
//          Bar bar;
//     };
//
// Isn't C++ great?
#[derive(Clone, Copy)]
enum CppDecl {
    Forward,
    Full,
}

struct DeclGroups<G: Clone + Copy> {
    forward: G,
    full: G,
}

impl<G: Clone + Copy> DeclGroups<G> {
    fn select(&self, decl: CppDecl) -> G {
        match decl {
            CppDecl::Forward => self.forward,
            CppDecl::Full => self.full,
        }
    }
}

#[derive(Eq, PartialEq)]
enum TypeLoc {
    OutsideRustNamespace,
    InsideRustNamespace,
    ForConstant,
}

struct CppTypeCtx<'a, G: Clone + Copy + Eq + Hash> {
    cpp: &'a mut String,
    ast: &'a AST,
    deps: &'a mut HashSet<(G, String)>,
    include_group: G,
    decl_groups: Option<DeclGroups<G>>,
    loc: TypeLoc,
    ns: &'a str,
}

impl<G: Clone + Copy + Eq + Hash> CppTypeCtx<'_, G> {
    fn append_cpp_signature(
        &mut self,
        returns: Option<&RustType>,
        name: &str,
        receiver: Option<&RustArg>,
        args: &[RustArg],
    ) {
        // Emit the return type
        if let Some(returns) = returns {
            self.append_cpp_type(returns, CppDecl::Full);
            self.cpp.push(' ');
        } else {
            self.cpp.push_str("void ");
        }

        // The function name goes in the middle in C
        self.cpp.push_str(name);

        // Emit the arguments
        self.cpp.push('(');
        if let Some(receiver) = receiver {
            self.append_cpp_type(&receiver.ty, CppDecl::Full);
            self.cpp.push(' ');
            self.cpp.push_str(&receiver.name);
        }
        for (i, arg) in args.iter().enumerate() {
            if receiver.is_some() || i > 0 {
                self.cpp.push_str(", ");
            }
            self.append_cpp_type(&arg.ty, CppDecl::Full);
            self.cpp.push(' ');
            self.cpp.push_str(&arg.name);
        }
        self.cpp.push(')');
    }

    fn append_cpp_type(&mut self, ty: &RustType, decl: CppDecl) {
        use RustType::*;
        match ty {
            Pair { other, .. } => self.append_cpp_type(other, decl),
            Verbatim(text) => self.cpp.push_str(text),
            Bool => self.cpp.push_str("bool"),

            U8 => {
                self.deps.insert((self.include_group, "<stdint.h>".into()));
                self.cpp.push_str("uint8_t");
            }
            U16 => {
                self.deps.insert((self.include_group, "<stdint.h>".into()));
                self.cpp.push_str("uint16_t");
            }
            U32 => {
                self.deps.insert((self.include_group, "<stdint.h>".into()));
                self.cpp.push_str("uint32_t");
            }
            Usize => {
                self.deps.insert((self.include_group, "<stdint.h>".into()));
                self.cpp.push_str("uintptr_t");
            }
            U64 => {
                self.deps.insert((self.include_group, "<stdint.h>".into()));
                self.cpp.push_str("uint64_t");
            }

            I8 => {
                self.deps.insert((self.include_group, "<stdint.h>".into()));
                self.cpp.push_str("int8_t");
            }
            I16 => {
                self.deps.insert((self.include_group, "<stdint.h>".into()));
                self.cpp.push_str("int16_t");
            }
            I32 => {
                self.deps.insert((self.include_group, "<stdint.h>".into()));
                self.cpp.push_str("int32_t");
            }
            Isize => {
                self.deps.insert((self.include_group, "<stdint.h>".into()));
                self.cpp.push_str("intptr_t");
            }
            I64 => {
                self.deps.insert((self.include_group, "<stdint.h>".into()));
                self.cpp.push_str("int64_t");
            }

            F32 => self.cpp.push_str("float"),
            F64 => self.cpp.push_str("double"),
            ForeignHandle => self.cpp.push_str("const void*"),
            RefStr | OwnStr => {
                if self.loc == TypeLoc::ForConstant {
                    self.deps
                        .insert((self.include_group, "<string_view>".into()));
                    self.cpp.push_str("std::string_view");
                } else {
                    self.deps.insert((self.include_group, "<string>".into()));
                    self.cpp.push_str("std::string");
                }
            }

            Struct(index) => {
                let name = &self.ast.structs[*index].name;
                if let Some(groups) = &self.decl_groups {
                    self.deps.insert((groups.select(decl), name.into()));
                }
                if self.loc == TypeLoc::OutsideRustNamespace {
                    _ = write!(self.cpp, "{}::", self.ns);
                }
                self.cpp.push_str(name);
            }
            Enum(index) => {
                let name = &self.ast.enums[*index].name;
                if let Some(groups) = &self.decl_groups {
                    self.deps.insert((groups.select(decl), name.into()));
                }
                if self.loc == TypeLoc::OutsideRustNamespace {
                    _ = write!(self.cpp, "{}::", self.ns);
                }
                self.cpp.push_str(name);
            }
            DynTrait(index) => {
                let name = &self.ast.traits[*index].name;
                if let Some(groups) = &self.decl_groups {
                    self.deps.insert((groups.select(decl), name.into()));
                }
                if self.loc == TypeLoc::OutsideRustNamespace {
                    _ = write!(self.cpp, "{}::", self.ns);
                }
                self.cpp.push_str(name);
            }

            Tuple(types) => {
                self.deps.insert((self.include_group, "<tuple>".into()));
                self.cpp.push_str("std::tuple<");
                for (i, ty) in types.iter().enumerate() {
                    if i > 0 {
                        self.cpp.push_str(", ");
                    }
                    self.append_cpp_type(ty, CppDecl::Full);
                }
                self.cpp.push('>');
            }

            Ptr(kind, inner) => match kind {
                RustPtr::Box => {
                    self.deps.insert((self.include_group, "<memory>".into()));
                    self.cpp.push_str("std::unique_ptr<");
                    self.append_cpp_type(inner, CppDecl::Forward);
                    self.cpp.push('>');
                }
                RustPtr::Rc => {
                    self.deps.insert((self.include_group, "<memory>".into()));
                    self.cpp.push_str("std::shared_ptr<");
                    self.append_cpp_type(inner, CppDecl::Forward);
                    self.cpp.push('>');
                }
            },

            Vector(inner) => {
                self.deps.insert((self.include_group, "<vector>".into()));
                self.cpp.push_str("std::vector<");
                self.append_cpp_type(inner, CppDecl::Forward);
                self.cpp.push('>');
            }

            Optional(inner) => {
                self.deps.insert((self.include_group, "<optional>".into()));
                self.cpp.push_str("std::optional<");
                self.append_cpp_type(inner, CppDecl::Full);
                self.cpp.push('>');
            }
        }
    }
}

fn append_cpp_val(cpp: &mut String, val: &RustVal) {
    use RustVal::*;
    match val {
        Bool(x) => _ = write!(cpp, "{x}"),

        U8(x) => _ = write!(cpp, "{x}u"),
        U16(x) => _ = write!(cpp, "{x}u"),
        U32(x) => _ = write!(cpp, "{x}u"),
        U64(x) => _ = write!(cpp, "{x}ull"),

        I8(x) => _ = write!(cpp, "{x}"),
        I16(x) => _ = write!(cpp, "{x}"),
        I32(x) => {
            if *x == std::i32::MIN {
                // Avoid a Visual C++ warning
                _ = write!(cpp, "{} - 1", x + 1);
            } else {
                _ = write!(cpp, "{x}");
            }
        }
        I64(x) => {
            if *x == std::i64::MIN {
                // Avoid a clang warning
                _ = write!(cpp, "{}ll - 1", x + 1);
            } else {
                _ = write!(cpp, "{x}ll");
            }
        }

        F32(x) => _ = write!(cpp, "{x:?}f"),
        F64(x) => _ = write!(cpp, "{x:?}"),

        Str(x) => {
            cpp.push_str("std::string_view(");
            append_cpp_quoted(cpp, x);
            _ = write!(cpp, ", {})", x.len());
        }
    }
}

fn append_cpp_quoted(cpp: &mut String, text: &str) {
    cpp.push('"');
    for c in text.chars() {
        match c {
            '\t' => cpp.push_str("\\t"),
            '\n' => cpp.push_str("\\n"),
            '\r' => cpp.push_str("\\r"),
            '\\' => cpp.push_str("\\\\"),
            '\"' => cpp.push_str("\\\""),
            c if (c as u32) < 0x20 => {
                _ = write!(cpp, "\\{:03o}", c as u32);
            }
            _ => cpp.push(c),
        }
    }
    cpp.push('"');
}

impl FnBuilder {
    fn write_to_cpp(
        &mut self,
        ctx: &CppCtx,
        ast: &AST,
        source_deps: &mut HashSet<(SourceGroup, String)>,
        out: &mut String,
        base_indent: &str,
    ) {
        let mut indent = 0;
        let mut callback = |line: &str| {
            if line.starts_with(&['}', ']', ')']) {
                indent -= 1;
            }
            _ = write!(out, "{base_indent}{}{line}\n", "    ".repeat(indent));
            if line.ends_with(&['{', '[', '(']) {
                indent += 1;
            }
        };
        for line in self.take_lines() {
            match line {
                Line::Plain(text) => {
                    text.split('\n').for_each(&mut callback);
                }
                Line::PlainAlt(when_false, when_true, flag) => match flag.get() {
                    false if when_false.is_empty() => continue,
                    false => when_false.split('\n').for_each(&mut callback),
                    true => when_true.split('\n').for_each(&mut callback),
                },
                Line::Decl(name, ty, text) => {
                    let mut decl_ty = String::new();
                    match ty {
                        None => decl_ty.push_str("auto"),
                        Some(ty) => CppTypeCtx {
                            cpp: &mut decl_ty,
                            ast,
                            deps: source_deps,
                            include_group: SourceGroup::Include,
                            decl_groups: None,
                            loc: TypeLoc::OutsideRustNamespace,
                            ns: &ctx.namespace,
                        }
                        .append_cpp_type(&ty, CppDecl::Full),
                    }
                    let text = format!("{decl_ty} {name} = {text};");
                    text.split('\n').for_each(&mut callback);
                }
            }
        }
    }
}


================================================
FILE: src/lib.rs
================================================
//! This is a simple but opinionated FFI system for Rust. It allows you to call
//! Rust code from other languages, and vice versa. Some design principles:
//!
//! - Intended for writing platform-agnostic Rust with platform-specific details in the host language
//! - FFI support is split into data (structs passed by copy) and code (traits passed by reference)
//! - Rather than have a separate schema language, the public API in your `lib.rs` is your schema
//! - The generated binding code is compact, dependency-free, and straightforward to integrate with
//!
//! ## Supported Features
//!
//! - Primitive types (`bool`, `i32`, `f64`, `String`, etc.)
//! - Tuples
//! - Structs
//! - Enums
//! - Top-level constants
//! - Top-level functions
//! - Traits (must be either `Box<dyn T>` or `Rc<dyn T>`)
//! - `Vec<T>`
//! - `Option<T>`
//! - `Box<T>`
//!
//! ## Simple Usage
//!
//! To get up and running:
//!
//! 1. Add `miniffi` to your `[build-dependencies]` in `Cargo.toml`:
//!
//!     ```text
//!     cargo add --build miniffi
//!     ```
//!
//! 2. Add the following code to the end of your `src/lib.rs` file:
//!
//!     ```
//!     # macro_rules! env { ($a:expr) => { $a } }
//!     # macro_rules! include { ($a:expr) => { $a } }
//!     include!(concat!(env!("OUT_DIR"), "/miniffi.rs"));
//!     ```
//!
//! 3. Add a `build.rs` script that calls [`build`](Target::build) on at least one [`Target`]:
//!
//!     ```no_run
//!     use miniffi::*;
//!
//!     fn main() {
//!         CppTarget::new().build();
//!     }
//!     ```
//!
//! 4. Import the generated bindings from the host language (see each target for details)
//!
//! ## Advanced Usage
//!
//! You can only build for one target at a time. However, the flexibility of
//! build scripts means you can use the same build script for different targets
//! in different situations using your own custom logic.
//!
//! For example, you may want to build for different host languages depending
//! on the value of cargo's `--target` flag:
//!
//! ```no_run
//! use miniffi::*;
//!
//! fn main() {
//!     let target = std::env::var("TARGET").unwrap();
//!     if target == "wasm32-unknown-unknown" {
//!         WasmTarget::new()
//!             .write_ts_to("../web/rust.ts")
//!             .set_panic_hook()
//!             .build();
//!     } else if target == "aarch64-apple-darwin" {
//!         SwiftTarget::new()
//!             .write_swift_to("../macos/rust.swift")
//!             .write_header_to("../macos/rust.h")
//!             .build();
//!     } else if target == "x86_64-pc-windows-msvc" {
//!         CppTarget::new()
//!             .write_source_to("../windows/rust.cpp")
//!             .write_header_to("../windows/rust.h")
//!             .build();
//!     } else {
//!         NullTarget::new().build();
//!     }
//! }
//! ```

mod ast;
mod cpp;
mod rust;
mod scan;
mod swift;
mod util;
mod wasm;

use ast::*;
use rust::*;
use std::fmt::Write;
use std::path::{Path, PathBuf};
use syn::spanned::Spanned;
use util::*;

pub use cpp::CppTarget;
pub use swift::SwiftTarget;
pub use wasm::WasmTarget;

use crate::scan::make_warning;

#[cfg(test)]
mod tests;

const DO_NOT_EDIT_COMMENT: &str = concat!(
    "This file was generated by miniffi v",
    env!("CARGO_PKG_VERSION"),
    ". Do not edit."
);

/// The common trait for all language-specific targets.
///
/// The following targets are available:
///
/// - [`CppTarget`] for C++
/// - [`SwiftTarget`] for Swift
/// - [`WasmTarget`] for JavaScript/TypeScript
/// - [`NullTarget`] otherwise
///
/// Typical usage involves creating a target with `new()`, chaining some
/// methods to configure it, and then calling [`build`](Target::build).
pub trait Target {
    /// Call this on the desired target from your `build.rs` script to generate
    /// the FFI bindings. It automatically locates your `src/lib.rs` file using
    /// the directory containing your `Cargo.toml` manifest, parses it to
    /// determine your packages public API, and then generates FFI bindings for
    /// that API.
    ///
    /// This will always generate the file `miniffi.rs` along with some
    /// additional files that are target-dependent. For example, the
    /// [`SwiftTarget`] additionally generates a `.swift` file and a `.h` file.
    /// The `miniffi.rs` file will be written inside of cargo's `target`
    /// directory, and is normally not something you'll need to think about too
    /// much (other than referencing it via `include!` in your `lib.rs` file).
    /// The other target-dependent files are intended to be included by you
    /// into the host language project. For example, you might add the `.swift`
    /// and `.h` files from the [`SwiftTarget`] to your Xcode project. You
    /// should probably also add all generated files to your `.gitignore` so
    /// they are not checked into source control as they are automatically
    /// generated.
    ///
    /// The returned [`BuildResult`] will be configured to automatically print
    /// some instructions for cargo when it is dropped. Typical usage involves
    /// just calling `build()` on the target without storing the return value.
    /// But you can use the return value to inspect the results of the build.
    /// You can also modify the return value to disable the printing of cargo
    /// instructions on drop if you need different behavior instead.
    fn build(&self) -> BuildResult {
        fn fail(error: &str) -> BuildResult {
            let mut result = BuildResult::default();
            result.errors.push(error.into());
            return result;
        }

        let Ok(input_dir) = std::env::var("CARGO_MANIFEST_DIR") else {
            return fail("missing environment variable: CARGO_MANIFEST_DIR");
        };
        let Ok(output_dir) = std::env::var("OUT_DIR") else {
            return fail("missing environment variable: OUT_DIR");
        };
        let input_path = PathBuf::from(input_dir).join("src").join("lib.rs");
        let output_path = PathBuf::from(output_dir).join("miniffi.rs");

        match std::fs::read_to_string(&input_path) {
            Err(err) => BuildResult {
                errors: vec![format!("Failed to read from {input_path:?}: {err}")],
                warnings: Vec::new(),
                input_path,
                output_files: Vec::new(),
                finish_on_drop: true,
            },
            Ok(contents) => {
                let input_file = FileData {
                    path: input_path,
                    contents,
                };
                let mut result = self.build_custom(input_file, output_path);
                result.finish_on_drop = true;
                result
            }
        }
    }

    /// This is the same as [`build`](Target::build) but without any of the
    /// cargo-specific logic (automatically locating and reading `src/lib.rs`
    /// and automatically printing out instructions for cargo). This can be
    /// useful for running miniffi outside of a cargo build script. If you're
    /// writing a cargo build script, you likely want to call
    /// [`build`](Target::build) instead.
    fn build_custom(&self, input_file: FileData, output_path: PathBuf) -> BuildResult;

    /// Set the edition for the generated Rust code. This can be necessary
    /// because different editions of Rust use different syntax.
    fn rust_edition(self, year: usize) -> Self;
}

/// Holds the result of calling [`build`](Target::build) or
/// [`build_custom`](Target::build_custom). May print out cargo
/// instructions and/or write files when dropped.
///
/// Typically you can just call `.build()` on a target and not use the return
/// value. But the return value is available if you need to inspect or modify
/// the build results.
///
/// The result returned from [`build`](Target::build) has `finish_on_drop` set
/// to true which means it will print out cargo instructions and write output
/// files when dropped. If you don't want this behavior (perhaps you need
/// something else to happen instead), then you should set `finish_on_drop` to
/// false before dropping the build result.
#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct BuildResult {
    pub input_path: PathBuf,
    pub output_files: Vec<FileData>,
    pub errors: Vec<String>,
    pub warnings: Vec<Warning>,
    pub finish_on_drop: bool,
}

impl BuildResult {
    /// Certain Rust features are not supported by miniffi. Using those
    /// features will generate a warning and cause the relevant code to be
    /// omitted from the FFI bindings. If you would like for these warnings
    /// to be errors instead (perhaps you want CI to fail when this happens),
    /// you can chain this method off of [`build`](Target::build):
    ///
    /// ```no_run
    /// use miniffi::*;
    ///
    /// fn main() {
    ///     CppTarget::new()
    ///         .build()
    ///         .convert_warnings_to_errors();
    /// }
    /// ```
    ///
    /// Doing this can have undesirable side effects. Because cargo build
    /// scripts run before your crate builds, a build script error stops the
    /// build before your crate is built. This can cause IDE features to stop
    /// working without an obvious cause since some Rust IDE plugins don't
    /// surface build script errors.
    pub fn convert_warnings_to_errors(mut self) -> Self {
        self.errors
            .extend(self.warnings.drain(..).map(|w| w.to_human_string()));
        self
    }

    /// This does the following:
    ///
    /// - Write all output files to the file system
    /// - Print `cargo:rerun-if-changed` lines for all files relevant to the build
    /// - Print `cargo::error` lines for everything in `errors`
    /// - Print `cargo:warning` lines for everything in `warnings`
    /// - Set `self.finish_on_drop` to `false` to avoid finishing on [`drop`](BuildResult::drop)
    pub fn finish(&mut self) {
        // Note: Cargo changed the directive prefix syntax from "cargo:" to
        // "cargo::" in version 0.78.0. The older syntax is mostly still
        // respected, so use it instead for better compatibility. The one
        // exception is that "cargo::error" was added after this but support
        // for "cargo:error" was not added. So this deliberately uses
        // "cargo::error" for errors. Older versions of rust will print an
        // error message when encountering "cargo::" at all so these will
        // still print an error.
        // https://github.com/rust-lang/cargo/commit/d45969a781a78e95215aba19898f397235c36b7c
        // https://github.com/rust-lang/cargo/commit/4f744776795eb3ccaf46530b0e37056c23641323
        println!("cargo:rerun-if-changed={}", self.input_path.display());

        for file in &mut self.output_files {
            println!("cargo:rerun-if-changed={}", file.path.display());
            write_file(&file.path, &file.contents, &mut self.errors);
        }

        for error in &self.errors {
            println!(
                "cargo::error=[miniffi] {}",
                error
                    .split('\n')
                    .collect::<Vec<_>>()
                    .join("\ncargo::error=")
            );
        }

        for warning in &self.warnings {
            println!(
                "cargo:warning=[miniffi] {}",
                warning
                    .to_human_string()
                    .split('\n')
                    .collect::<Vec<_>>()
                    .join("\ncargo:warning=")
            );
        }

        self.finish_on_drop = false;
    }
}

impl Drop for BuildResult {
    /// If `finish_on_drop` is true, dropping a `BuildResult` runs `finish()`
    /// before the drop. If `finish_on_drop` is false, then dropping a
    /// `BuildResult` does nothing.
    fn drop(&mut self) {
        if self.finish_on_drop {
            self.finish();
        }
    }
}

/// Part of a [`BuildResult`].
#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct Warning {
    pub path: PathBuf,
    pub line: usize,
    pub column: usize,
    pub len: usize,
    pub message: String,
    pub code: String,
    pub note: String,
}

impl Warning {
    /// Returns a single-line string containing the file location and message.
    /// Similar to Rust's "short" message format. For example:
    ///
    /// ```text
    /// /home/user/foo/src/lib.rs:42:11: unsupported type `AtomicBool` for field `flag`
    /// ```
    pub fn to_short_string(&self) -> String {
        format!(
            "{}:{}:{}: {}{}",
            self.path.display(),
            self.line,
            self.column,
            self.message,
            match self.note.as_str() {
                "" => String::new(),
                note => format!(" ({note})"),
            }
        )
    }

    /// Returns a multi-line string containing the file location, message, and
    /// the relevant line of code. Similar to Rust's "human" message format.
    /// For example:
    ///
    /// ```text
    /// unsupported type `AtomicBool` for field `flag`
    ///   --> /home/user/foo/src/lib.rs:42:11
    ///    |
    /// 42 |     flag: AtomicBool,
    ///    |           ^^^^^^^^^^
    /// ```
    pub fn to_human_string(&self) -> String {
        let line = self.line.to_string();
        let indent = " ".repeat(line.len());
        format!(
            "{}\n{indent}--> {}:{}:{}\n{indent} |\n{line} | {}\n{indent} |{}{}{}{}\n",
            self.message,
            self.path.display(),
            self.line,
            self.column,
            self.code,
            " ".repeat(self.column),
            "^".repeat(self.len.max(1)),
            if self.note.is_empty() { "" } else { " " },
            self.note
        )
    }
}

/// Part of a [`BuildResult`].
#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct FileData {
    pub path: PathBuf,
    pub contents: String,
}

struct CommonOptions {
    edition: usize,
}

impl Default for CommonOptions {
    fn default() -> CommonOptions {
        CommonOptions { edition: 2024 }
    }
}

trait Compile {
    fn common_options(&mut self) -> &mut CommonOptions;
    fn compile(&self, ast: AST, rust_path: PathBuf) -> Vec<FileData>;
}

impl<T: Compile> Target for T {
    fn rust_edition(mut self, year: usize) -> Self {
        self.common_options().edition = year;
        self
    }

    fn build_custom(&self, input_file: FileData, output_path: PathBuf) -> BuildResult {
        let mut output_files = Vec::new();
        let mut errors = Vec::new();
        let mut warnings = Vec::new();

        if !input_file.contents.contains("miniffi.rs") {
            let code = r#"include!(concat!(env!("OUT_DIR"), "/miniffi.rs"));"#;
            let file = input_file
                .path
                .file_name()
                .unwrap_or(input_file.path.as_os_str());
            errors.push(format!("Please add this to the end of {file:?}: {code}"));
        }

        match syn::parse_file(&input_file.contents) {
            Err(err) => {
                let message = format!("{err}");
                warnings.push(make_warning(&input_file, message, "", err.span()));
            }
            Ok(ast) => {
                let ast = scan::scan_ast(&input_file, &ast, &mut warnings);
                output_files = self.compile(ast, output_path);
            }
        }

        BuildResult {
            input_path: input_file.path,
            output_files,
            errors,
            warnings,
            finish_on_drop: false,
        }
    }
}

/// Use this target when there is no host language.
///
/// The null target creates an empty `miniffi.rs` file. That can be useful if
/// you want to build FFI support for some configurations and not others.
///
/// For example, the following `build.rs` script only builds FFI support when
/// targeting WASM (such as with `cargo build --target=wasm32-unknown-unknown`)
/// and not otherwise (such as running tests with `cargo test`):
///
/// ```no_run
/// use miniffi::*;
///
/// fn main() {
///     let target = std::env::var("TARGET").unwrap();
///     if target == "wasm32-unknown-unknown" {
///         WasmTarget::new().build();
///     } else {
///         NullTarget::new().build();
///     }
/// }
/// ```
pub struct NullTarget {
    common_options: CommonOptions,
}

impl NullTarget {
    pub fn new() -> NullTarget {
        NullTarget {
            common_options: CommonOptions::default(),
        }
    }
}

impl Compile for NullTarget {
    fn common_options(&mut self) -> &mut CommonOptions {
        &mut self.common_options
    }

    fn compile(&self, _ast: AST, rust_path: PathBuf) -> Vec<FileData> {
        vec![FileData {
            path: rust_path,
            contents: String::new(),
        }]
    }
}

fn write_file(path: &Path, contents: &str, errors: &mut Vec<String>) {
    if let Some(parent) = path.parent() {
        if let Err(err) = std::fs::create_dir_all(parent) {
            errors.push(format!("Failed to create directory {parent:?}: {err}"));
        }
    }

    if let Ok(existing) = std::fs::read(&path) {
        if existing == contents.as_bytes() {
            return; // Avoid unnecessary rebuilds
        }
    }

    if let Err(err) = std::fs::write(&path, contents) {
        errors.push(format!("Failed to write to {path:?}: {err}"));
    }
}


================================================
FILE: src/rust.rs
================================================
use super::*;
use std::borrow::Cow;

#[derive(Default)]
pub struct RustSyntax {
    edition: usize,
}

impl RustSyntax {
    pub fn with_edition(edition: usize) -> RustSyntax {
        RustSyntax { edition }
    }

    pub fn unsafe_no_mangle(&self) -> &'static str {
        if self.edition >= 2024 {
            "#[unsafe(no_mangle)]"
        } else {
            "#[no_mangle]"
        }
    }

    pub fn unsafe_extern(&self) -> &'static str {
        if self.edition >= 2024 {
            "unsafe extern"
        } else {
            "extern"
        }
    }
}

pub fn append_rust_type(rust: &mut String, ast: &AST, ty: &RustType) {
    use RustType::*;
    match ty {
        Pair { rust: inner, .. } => append_rust_type(rust, ast, inner),
        Verbatim(text) => rust.push_str(text),
        Bool => rust.push_str("bool"),

        U8 => rust.push_str("u8"),
        U16 => rust.push_str("u16"),
        U32 => rust.push_str("u32"),
        Usize => rust.push_str("usize"),
        U64 => rust.push_str("u64"),

        I8 => rust.push_str("i8"),
        I16 => rust.push_str("i16"),
        I32 => rust.push_str("i32"),
        Isize => rust.push_str("isize"),
        I64 => rust.push_str("i64"),

        F32 => rust.push_str("f32"),
        F64 => rust.push_str("f64"),

        RefStr => rust.push_str("&str"),
        OwnStr => rust.push_str("String"),

        Struct(index) => rust.push_str(&ast.structs[*index].name),
        Enum(index) => rust.push_str(&ast.enums[*index].name),

        DynTrait(index) => {
            rust.push_str("dyn ");
            rust.push_str(&ast.traits[*index].name);
        }

        Ptr(kind, inner) => {
            rust.push_str(kind.path());
            rust.push('<');
            append_rust_type(rust, ast, &inner);
            rust.push('>');
        }

        Vector(inner) => {
            rust.push_str("Vec<");
            append_rust_type(rust, ast, &inner);
            rust.push('>');
        }

        Tuple(types) => {
            rust.push('(');
            for (i, ty) in types.iter().enumerate() {
                append_rust_type(rust, ast, ty);
                if i + 1 < types.len() {
                    rust.push_str(", ");
                } else if types.len() == 1 {
                    rust.push(',');
                }
            }
            rust.push(')');
        }

        Optional(inner) => {
            rust.push_str("Option<");
            append_rust_type(rust, ast, &inner);
            rust.push('>');
        }

        ForeignHandle => rust.push_str("*const u8"),
    }
}

pub fn append_rust_default_val(rust: &mut String, ast: &AST, ty: &RustType) {
    use RustType::*;
    match ty {
        Bool => rust.push_str("false"),

        U8 | U16 | U32 | Usize | U64 | I8 | I16 | I32 | Isize | I64 => rust.push_str("0"),

        F32 | F64 => rust.push_str("0.0"),

        RefStr => rust.push_str("\"\""),
        OwnStr => rust.push_str("String::new()"),

        Struct(index) => {
            let s = &ast.structs[*index];
            rust.push_str(&s.name);
            if s.fields.is_empty() {
                rust.push_str(" {}");
            } else {
                rust.push_str(" { ");
                for (i, f) in s.fields.iter().enumerate() {
                    if i > 0 {
                        rust.push_str(", ");
                    }
                    rust.push_str(&f.name);
                    rust.push_str(": ");
                    append_rust_default_val(rust, ast, &f.ty);
                }
                rust.push_str(" }");
            }
        }

        Tuple(types) => {
            rust.push('(');
            for (i, ty) in types.iter().enumerate() {
                append_rust_default_val(rust, ast, ty);
                if i + 1 < types.len() {
                    rust.push_str(", ");
                } else if types.len() == 1 {
                    rust.push(',');
                }
            }
            rust.push(')');
        }

        ForeignHandle => rust.push_str("std::ptr::null()"),

        _ => rust.push_str("unreachable!()"),
    }
}

impl FnBuilder {
    pub fn write_to_rust(&mut self, ast: &AST, out: &mut String, base_indent: &str) {
        let mut indent = 0;
        let mut callback = |line: &str| {
            if line.starts_with(&['}', ']', ')']) {
                indent -= 1;
            }
            _ = write!(out, "{base_indent}{}{line}\n", "    ".repeat(indent));
            if line.ends_with(&['{', '[', '(']) {
                indent += 1;
            }
        };
        for line in self.take_lines() {
            match line {
                Line::Plain(text) => {
                    text.split('\n').for_each(&mut callback);
                }
                Line::PlainAlt(when_false, when_true, flag) => match flag.get() {
                    false if when_false.is_empty() => continue,
                    false => when_false.split('\n').for_each(&mut callback),
                    true => when_true.split('\n').for_each(&mut callback),
                },
                Line::Decl(name, ty, text) => {
                    let mut decl_ty = String::new();
                    if let Some(ty) = ty {
                        decl_ty.push_str(": ");
                        append_rust_type(&mut decl_ty, ast, &ty);
                    }
                    let text = format!("let {name}{decl_ty} = {text};");
                    text.split('\n').for_each(&mut callback);
                }
            }
        }
    }
}

pub fn is_snake_case(name: &str) -> bool {
    let name = name.trim_matches('_');
    !name.contains("__") && !name.chars().any(char::is_uppercase)
}

pub fn is_camel_case(name: &str) -> bool {
    let name = name.trim_matches('_');
    let mut chars = name.chars();
    !chars.next().map(char::is_lowercase).unwrap_or(false)
        && !name.contains("__")
        && !name.chars().zip(chars).any(|(a, b)| {
            let has_case = |c: char| c.to_uppercase().next() != c.to_lowercase().next();
            (has_case(a) && b == '_') || (a == '_' && has_case(b))
        })
}

pub fn allow_non_snake_case(rust: &mut String, name: &str) {
    if !is_snake_case(name) {
        rust.push_str("\n#[allow(non_snake_case)]");
    }
}

pub fn allow_non_camel_case_types(rust: &mut String, name: &str) {
    if !is_camel_case(name) {
        rust.push_str("\n#[allow(non_camel_case_types)]");
    }
}

pub fn rust_decl_ctor(
    rust: &mut FnBuilder,
    var_name: &str,
    ctor_name: &str,
    fields: &Vec<RustField>,
    item_names: Vec<Cow<'_, str>>,
) {
    if fields.is_empty() {
        rust.decl(var_name, ctor_name.to_string());
    } else if fields.iter().any(|arg| starts_with_digit(&arg.name)) {
        let args = rust.find_args(
            &fields
                .iter()
                .zip(item_names)
                .map(|(f, name)| RustArg {
                    name: name.to_string(),
                    ty: f.ty.clone(),
                })
                .collect(),
            RefInline,
        );
        rust.decl(var_name, format!("{ctor_name}({args})"));
    } else {
        let fields = rust.find_fields(
            fields,
            item_names,
            RefInline,
            &format!("{ctor_name} {{ "),
            " }",
        );
        rust.decl(var_name, fields);
    }
}

pub fn add_common_rust_helpers(syntax: &RustSyntax, helpers: &mut HelperSet<(), String>) {
    helpers.add(
        "_ffi_read",
        r"
fn _ffi_read<T: Copy>(ptr: &mut *const u8) -> T {
    let val = unsafe { (*ptr as *const T).read_unaligned() };
    *ptr = unsafe { ptr.byte_offset(std::mem::size_of::<T>() as isize) };
    val
}
",
    );

    helpers.add(
        "_ffi_write",
        r"
fn _ffi_write<T: Copy>(val: T, buf: &mut Vec<u8>) {
    let ptr = std::ptr::addr_of!(val) as *const u8;
    let len = std::mem::size_of::<T>();
    buf.extend_from_slice(unsafe { std::slice::from_raw_parts(ptr, len) });
}
",
    );

    helpers.add(
        "_ffi_alloc",
        format!(
            r#"
{}
extern "C" fn _ffi_alloc(len: usize) -> *const u8 {{
    Box::into_raw([0 as u8].repeat(len).into_boxed_slice()) as *const u8
}}
"#,
            syntax.unsafe_no_mangle()
        ),
    );

    helpers.add(
        "_ffi_dealloc",
        format!(
            r#"
{}
extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) {{
    drop(unsafe {{ Vec::from_raw_parts(ptr, 0, capacity) }});
}}
"#,
            syntax.unsafe_no_mangle()
        ),
    );

    helpers
        .add(
            "_ffi_string_from_host",
            r"
fn _ffi_string_from_host(ptr: *const u8, len: usize) -> String {
    unsafe { String::from_raw_parts(ptr as *mut u8, len, len) }
}
",
        )
        .add_dep("_ffi_alloc");

    helpers
        .add(
            "_ffi_string_to_host",
            r"
fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) {
    let buf = std::mem::ManuallyDrop::new(buf.into_bytes());
    (buf.as_ptr(), buf.len(), buf.capacity())
}
",
        )
        .add_dep("_ffi_dealloc");

    helpers
        .add(
            "_ffi_buf_from_host",
            r"
fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) {
    let len = unsafe { end.byte_offset_from(ptr) } as usize;
    drop(unsafe { Vec::from_raw_parts(ptr as *mut u8, 0, len) });
}
",
        )
        .add_dep("_ffi_alloc");

    helpers
        .add(
            "_ffi_buf_to_host",
            r"
fn _ffi_buf_to_host(buf: Vec<u8>) -> (*const u8, usize) {
    let buf = std::mem::ManuallyDrop::new(buf);
    (buf.as_ptr(), buf.capacity())
}
",
        )
        .add_dep("_ffi_dealloc");
}


================================================
FILE: src/scan.rs
================================================
use super::*;
use std::collections::HashSet;
use syn::{Attribute, Fields, ext::IdentExt};

pub fn scan_ast(file: &FileData, parsed: &syn::File, warnings: &mut Vec<Warning>) -> AST {
    use syn::{Item, Visibility::Public};

    let mut ast = AST {
        structs: Vec::new(),
        enums: Vec::new(),
        traits: Vec::new(),
        consts: Vec::new(),
        fns: Vec::new(),
    };

    // Pass 1: Scan for type names
    for item in &parsed.items {
        match item {
            Item::Struct(item) => {
                let Public(_) = item.vis else { continue };
                ast.structs.push(RustStruct {
                    name: item.ident.unraw().to_string(),
                    fields: Vec::new(),
                    derives_partial_eq: derives_partial_eq(&item.attrs),
                });
            }

            Item::Enum(item) => {
                let Public(_) = item.vis else { continue };
                ast.enums.push(RustEnum {
                    name: item.ident.unraw().to_string(),
                    variants: Vec::new(),
                    derives_partial_eq: derives_partial_eq(&item.attrs),
                });
            }

            Item::Trait(item) => {
                let Public(_) = item.vis else { continue };
                ast.traits.push(RustTrait {
                    name: item.ident.unraw().to_string(),
                    fns: Vec::new(),
                });
            }

            _ => continue,
        }
    }

    // Pass 2: Scan for type contents
    'next_item: for item in &parsed.items {
        match item {
            Item::Struct(item) => {
                let Public(_) = item.vis else { continue };
                let name = item.ident.unraw().to_string();
                let fields = match parse_fields(file, &ast, &item.fields, ("struct", &name)) {
                    Ok(fields) => fields,
                    Err(warning) => {
                        warnings.push(warning);
                        continue;
                    }
                };
                for s in &mut ast.structs {
                    if s.name == name {
                        s.fields = fields;
                        break;
                    }
                }
            }

            Item::Enum(item) => {
                let Public(_) = item.vis else { continue };
                let enum_name = item.ident.unraw().to_string();
                let mut variants = Vec::new();
                let mut discriminant = 0;

                for v in &item.variants {
                    let name = v.ident.unraw().to_string();
                    let full_name = format!("{enum_name}::{name}");
                    let fields = match parse_fields(file, &ast, &v.fields, ("variant", &full_name))
                    {
                        Ok(fields) => fields,
                        Err(warning) => {
                            warnings.push(warning);
                            continue 'next_item;
                        }
                    };
                    if let Some((_, expr)) = &v.discriminant {
                        if let Some(value) = expr_to_numeric_literal(expr) {
                            discriminant = value;
                        } else {
                            warnings.push(unsupported(
                                file,
                                "discriminant",
                                expr.span(),
                                ("variant", &name),
                                Some(("enum", &enum_name)),
                                "must be an integer literal",
                            ));
                        }
                    }
                    variants.push(RustVariant {
                        name,
                        discriminant,
                        fields,
                    });
                    discriminant = discriminant.wrapping_add(1);
                }

                for e in &mut ast.enums {
                    if e.name == enum_name {
                        e.variants = variants;
                        break;
                    }
                }
            }

            _ => continue,
        }
    }

    // Prune infinitely-sized types so the code generators don't stack overflow
    for i in 0..ast.structs.len() {
        for j in 0..ast.structs[i].fields.len() {
            if is_infinite_size(&ast, &ast.structs[i].fields[j].ty) {
                ast.structs[i].fields[j].ty = RustType::Tuple(Vec::new());
            }
        }
    }

    // Pass 3: Scan for code
    'next_item: for item in &parsed.items {
        match item {
            Item::Const(item) => {
                let Public(_) = item.vis else { continue };
                let name = item.ident.unraw().to_string();
                let Some(ty) = to_rust_type(&ast, &item.ty) else {
                    warnings.push(unsupported(
                        file,
                        "type",
                        item.ty.span(),
                        ("constant", &name),
                        None,
                        "",
                    ));
                    continue;
                };
                let Some(val) = to_rust_val(&item.expr, &ty) else {
                    warnings.push(unsupported(
                        file,
                        "value",
                        item.expr.span(),
                        ("constant", &name),
                        None,
                        "only literals are supported",
                    ));
                    continue;
                };
                ast.consts.push(RustConst { name, ty, val });
            }

            Item::Fn(item) => {
                let Public(_) = item.vis else { continue };
                let f = match to_rust_fn(file, &ast, &item.sig, None) {
                    Ok(f) => f,
                    Err(warning) => {
                        warnings.push(warning);
                        continue 'next_item;
                    }
                };
                ast.fns.push(f);
            }

            Item::Trait(item) => {
                let Public(_) = item.vis else { continue };
                let name = item.ident.unraw().to_string();
                let mut fns = Vec::new();

                for item in &item.items {
                    let syn::TraitItem::Fn(item) = item else {
                        warnings.push(unsupported(
                            file,
                            "item",
                            item.span(),
                            ("trait", &name),
                            None,
                            "only functions are supported",
                        ));
                        continue 'next_item;
                    };
                    let f = match to_rust_fn(file, &ast, &item.sig, Some(&name)) {
                        Ok(f) => f,
                        Err(warning) => {
                            warnings.push(warning);
                            continue 'next_item;
                        }
                    };
                    fns.push(f);
                }

                for t in &mut ast.traits {
                    if t.name == name {
                        t.fns = fns;
                        break;
                    }
                }
            }

            _ => continue,
        }
    }

    ast
}

// Detect "#[derive(PartialEq)]"
fn derives_partial_eq(attrs: &[Attribute]) -> bool {
    for attr in attrs {
        if let syn::Meta::List(syn::MetaList { path, .. }) = &attr.meta {
            if path.is_ident("derive") {
                let mut found = false;
                _ = attr.parse_nested_meta(|meta| {
                    if meta.path.is_ident("PartialEq") {
                        found = true;
                    }
                    Ok(())
                });
                if found {
                    return true;
                }
            }
        }
    }
    false
}

fn parse_fields(
    file: &FileData,
    ast: &AST,
    fields: &Fields,
    extra: (&str, &str),
) -> Result<Vec<RustField>, Warning> {
    let mut result = Vec::new();

    match fields {
        syn::Fields::Unit => {}

        syn::Fields::Unnamed(item) => {
            for (i, field) in item.unnamed.iter().enumerate() {
                let name = format!("{i}");
                let Some(ty) = to_rust_type(&ast, &field.ty) else {
                    return Err(unsupported(
                        file,
                        "type",
                        field.ty.span(),
                        ("field", &name),
                        Some(extra),
                        "",
                    ));
                };
                result.push(RustField { name, ty });
            }
        }

        syn::Fields::Named(item) => {
            for field in &item.named {
                let name = field.ident.as_ref().unwrap().to_string();
                let Some(ty) = to_rust_type(&ast, &field.ty) else {
                    return Err(unsupported(
                        file,
                        "type",
                        field.ty.span(),
                        ("field", &name),
                        Some(extra),
                        "",
                    ));
                };
                result.push(RustField { name, ty });
            }
        }
    }

    Ok(result)
}

fn to_rust_fn(
    file: &FileData,
    ast: &AST,
    sig: &syn::Signature,
    trait_name: Option<&str>,
) -> Result<RustFn, Warning> {
    let name = sig.ident.unraw().to_string();
    let mut args = Vec::new();
    let mut self_span = None;
    let extra = trait_name.map(|name| ("trait", name));

    for arg in &sig.inputs {
        match arg {
            syn::FnArg::Typed(arg) => {
                let Some(name) = pat_to_single_ident(&arg.pat) else {
                    return Err(unsupported(
                        file,
                        "pattern",
                        arg.pat.span(),
                        ("function", &name),
                        None,
                        "only identifiers are supported",
                    ));
                };
                let Some(ty) = to_rust_type(ast, &arg.ty) else {
                    return Err(unsupported(
                        file,
                        "type",
                        arg.ty.span(),
                        ("argument", &name),
                        extra,
                        "",
                    ));
                };
                args.push(RustArg { name, ty });
            }

            syn::FnArg::Receiver(arg) => {
                if arg.reference.is_none() || arg.colon_token.is_some() || arg.mutability.is_some()
                {
                    return Err(unsupported(
                        file,
                        "receiver",
                        arg.span(),
                        ("argument", &name),
                        extra,
                        "use `&self` instead",
                    ));
                }
                self_span = Some(arg.self_token.span());
            }
        }
    }

    // All trait methods must have a "self" receiver
    match (trait_name, self_span) {
        (Some(trait_name), None) => {
            return Err(unsupported(
                file,
                "function",
                sig.ident.span(),
                ("trait", trait_name),
                None,
                "methods on public traits must use `&self`",
            ));
        }
        (None, Some(self_span)) => {
            return Err(unsupported(
                file,
                "argument",
                self_span,
                ("function", &name),
                extra,
                "",
            ));
        }
        _ => {}
    }

    let returns = match &sig.output {
        syn::ReturnType::Default => None,
        syn::ReturnType::Type(_, ty) => {
            let Some(ty) = to_rust_type(ast, &ty) else {
                return Err(unsupported(
                    file,
                    "return type",
                    ty.span(),
                    ("function", &name),
                    extra,
                    "",
                ));
            };
            let mut names = NameSet::default();
            for arg in &args {
                names.add(arg.name.clone());
            }
            let name = names.create("ret");
            Some(RustArg { name, ty })
        }
    };

    Ok(RustFn {
        name,
        args,
        returns,
    })
}

fn to_rust_type(ast: &AST, ty: &syn::Type) -> Option<RustType> {
    if let Some(ident) = type_to_single_ident(ty) {
        return match () {
            () if ident == "bool" => Some(RustType::Bool),

            () if ident == "u8" => Some(RustType::U8),
            () if ident == "u16" => Some(RustType::U16),
            () if ident == "u32" => Some(RustType::U32),
            () if ident == "usize" => Some(RustType::Usize),
            () if ident == "u64" => Some(RustType::U64),

            () if ident == "i8" => Some(RustType::I8),
            () if ident == "i16" => Some(RustType::I16),
            () if ident == "i32" => Some(RustType::I32),
            () if ident == "isize" => Some(RustType::Isize),
            () if ident == "i64" => Some(RustType::I64),

            () if ident == "f32" => Some(RustType::F32),
            () if ident == "f64" => Some(RustType::F64),

            () if ident == "String" => Some(RustType::OwnStr),

            _ => {
                if let Some((i, _)) = ast
                    .structs
                    .iter()
                    .enumerate()
                    .find(|(_, s)| ident == &s.name)
                {
                    Some(RustType::Struct(i))
                } else if let Some((i, _)) =
                    ast.enums.iter().enumerate().find(|(_, e)| ident == &e.name)
                {
                    Some(RustType::Enum(i))
                } else {
                    None
                }
            }
        };
    }

    if let Some((name, inner)) = type_to_single_ident_with_argument(ast, ty) {
        return if name == "Rc" || name == "rc::Rc" || name == "std::rc::Rc" {
            match &inner {
                RustType::DynTrait(_) => Some(RustType::Ptr(RustPtr::Rc, inner.into())),
                _ => None,
            }
        } else if name == "Box" || name == "boxed::Box" || name == "std::boxed::Box" {
            Some(RustType::Ptr(RustPtr::Box, inner.into()))
        } else if name == "Vec" || name == "vec::Vec" || name == "std::vec::Vec" {
            Some(RustType::Vector(inner.into()))
        } else if name == "Option" || name == "option::Option" || name == "std::option::Option" {
            Some(RustType::Optional(inner.into()))
        } else {
            None
        };
    }

    match ty {
        syn::Type::Tuple(syn::TypeTuple { elems, .. }) => {
            let mut types = Vec::new();
            for elem in elems {
                types.push(to_rust_type(ast, elem)?);
            }
            Some(RustType::Tuple(types))
        }

        syn::Type::Reference(syn::TypeReference {
            mutability: None,
            elem,
            ..
        }) => {
            if let Some(ident) = type_to_single_ident(elem) {
                match () {
                    () if ident == "str" => Some(RustType::RefStr),
                    _ => None,
                }
            } else {
                None
            }
        }

        syn::Type::TraitObject(syn::TypeTraitObject { bounds, .. }) if bounds.len() == 1 => {
            if let syn::TypeParamBound::Trait(syn::TraitBound { path, .. }) = &bounds[0] {
                if let Some(ident) = path.get_ident() {
                    if let Some((i, _)) = ast
                        .traits
                        .iter()
                        .enumerate()
                        .find(|(_, t)| ident == &t.name)
                    {
                        Some(RustType::DynTrait(i))
                    } else {
                        None
                    }
                } else {
                    None
                }
            } else {
                None
            }
        }

        _ => None,
    }
}

fn to_rust_val(expr: &syn::Expr, ty: &RustType) -> Option<RustVal> {
    match expr {
        syn::Expr::Lit(syn::ExprLit {
            lit: syn::Lit::Bool(lit),
            ..
        }) => match ty {
            RustType::Bool => Some(RustVal::Bool(lit.value())),
            _ => None,
        },

        syn::Expr::Lit(syn::ExprLit {
            lit: syn::Lit::Int(lit),
            ..
        }) => match ty {
            RustType::U8 => Some(RustVal::U8(lit.base10_parse().ok()?)),
            RustType::U16 => Some(RustVal::U16(lit.base10_parse().ok()?)),
            RustType::U32 => Some(RustVal::U32(lit.base10_parse().ok()?)),
            RustType::U64 => Some(RustVal::U64(lit.base10_parse().ok()?)),

            RustType::I8 => Some(RustVal::I8(lit.base10_parse().ok()?)),
            RustType::I16 => Some(RustVal::I16(lit.base10_parse().ok()?)),
            RustType::I32 => Some(RustVal::I32(lit.base10_parse().ok()?)),
            RustType::I64 => Some(RustVal::I64(lit.base10_parse().ok()?)),

            _ => None,
        },

        syn::Expr::Lit(syn::ExprLit {
            lit: syn::Lit::Float(lit),
            ..
        }) => match ty {
            RustType::F32 => Some(RustVal::F32(lit.base10_parse().ok()?)),
            RustType::F64 => Some(RustVal::F64(lit.base10_parse().ok()?)),
            _ => None,
        },

        syn::Expr::Lit(syn::ExprLit {
            lit: syn::Lit::Str(lit),
            ..
        }) => match ty {
            RustType::RefStr => Some(RustVal::Str(lit.value())),
            _ => None,
        },

        syn::Expr::Unary(syn::ExprUnary {
            op: syn::UnOp::Neg(_),
            expr,
            ..
        }) => match &**expr {
            syn::Expr::Lit(syn::ExprLit {
                lit: syn::Lit::Int(lit),
                ..
            }) => match ty {
                RustType::I8 => Some(RustVal::I8(
                    format!("-{}", lit.base10_digits()).parse().ok()?,
                )),
                RustType::I16 => Some(RustVal::I16(
                    format!("-{}", lit.base10_digits()).parse().ok()?,
                )),
                RustType::I32 => Some(RustVal::I32(
                    format!("-{}", lit.base10_digits()).parse().ok()?,
                )),
                RustType::I64 => Some(RustVal::I64(
                    format!("-{}", lit.base10_digits()).parse().ok()?,
                )),
                _ => None,
            },

            syn::Expr::Lit(syn::ExprLit {
                lit: syn::Lit::Float(lit),
                ..
            }) => match ty {
                RustType::F32 => Some(RustVal::F32(
                    format!("-{}", lit.base10_digits()).parse().ok()?,
                )),
                RustType::F64 => Some(RustVal::F64(
                    format!("-{}", lit.base10_digits()).parse().ok()?,
                )),
                _ => None,
            },

            _ => None,
        },

        _ => None,
    }
}

fn expr_to_numeric_literal<T>(expr: &syn::Expr) -> Option<T>
where
    T: std::str::FromStr,
    <T as std::str::FromStr>::Err: std::fmt::Display,
{
    match expr {
        // Positive
        syn::Expr::Lit(syn::ExprLit {
            lit: syn::Lit::Int(lit),
            ..
        }) => lit.base10_parse().ok(),

        // Negative
        syn::Expr::Unary(syn::ExprUnary {
            op: syn::UnOp::Neg(_),
            expr,
            ..
        }) => match &**expr {
            syn::Expr::Lit(syn::ExprLit {
                lit: syn::Lit::Int(lit),
                ..
            }) => format!("-{}", lit.base10_digits()).parse().ok(),
            _ => None,
        },

        _ => None,
    }
}

fn path_to_string_with_argument(ast: &AST, path: &syn::Path) -> Option<(String, RustType)> {
    let last = path.segments.last()?;
    let syn::PathArguments::AngleBracketed(inner) = &last.arguments else {
        return None;
    };
    if inner.args.len() == 1 {
        if let syn::GenericArgument::Type(ty) = &inner.args[0] {
            if let Some(inner) = to_rust_type(ast, ty) {
                let mut name = String::new();
                for (i, segment) in path.segments.iter().enumerate() {
                    if i + 1 < path.segments.len() {
                        let syn::PathArguments::None = segment.arguments else {
                            return None;
                        };
                    }
                    if i > 0 {
                        name.push_str("::");
                    }
                    name.push_str(&segment.ident.unraw().to_string());
                }
                return Some((name, inner));
            }
        }
    }
    None
}

fn type_to_single_ident(ty: &syn::Type) -> Option<&syn::Ident> {
    if let syn::Type::Path(syn::TypePath { qself: None, path }) = ty {
        return path.get_ident();
    }
    None
}

fn type_to_single_ident_with_argument(ast: &AST, ty: &syn::Type) -> Option<(String, RustType)> {
    if let syn::Type::Path(syn::TypePath { qself: None, path }) = ty {
        return path_to_string_with_argument(ast, path);
    }
    None
}

fn pat_to_single_ident(pat: &syn::Pat) -> Option<String> {
    match pat {
        syn::Pat::Ident(syn::PatIdent { ident, .. }) => Some(ident.unraw().to_string()),
        syn::Pat::Wild(_) => Some("_".to_string()),
        _ => None,
    }
}

fn unsupported(
    file: &FileData,
    what: &str,
    span: proc_macro2::Span,
    outer: (&str, &str),
    extra: Option<(&str, &str)>,
    note: &str,
) -> Warning {
    let text = match span.source_text() {
        None => what.into(),
        Some(text) => format!("{what} `{text}`"),
    };
    let mut message = format!("unsupported {text} for {} `{}`", outer.0, outer.1);
    if let Some((what, name)) = extra {
        _ = write!(message, " in {what} `{name}`");
    }
    make_warning(file, message, note, span)
}

pub fn make_warning(
    file: &FileData,
    message: String,
    note: &str,
    span: proc_macro2::Span,
) -> Warning {
    let start = span.start();
    let end = span.end();
    let line = start.line;
    let column = start.column + 1;
    let code = file
        .contents
        .lines()
        .skip(line.saturating_sub(1))
        .next()
        .unwrap_or("")
        .to_string();
    let len = if end.line == start.line {
        code.len().min(end.column)
    } else {
        code.len()
    }
    .saturating_sub(start.column);
    Warning {
        path: file.path.clone(),
        line,
        column,
        len,
        message,
        code,
        note: note.to_string(),
    }
}

fn is_infinite_size(ast: &AST, ty: &RustType) -> bool {
    fn visit(ast: &AST, ty: &RustType, visited: &mut HashSet<RustType>) -> bool {
        use RustType::*;
        match ty {
            Struct(struct_index) => {
                if visited.contains(ty) {
                    return true;
                }
                visited.insert(ty.clone());
                ast.structs[*struct_index]
                    .fields
                    .iter()
                    .any(|f| visit(ast, &f.ty, visited))
            }
            Tuple(types) => types.iter().any(|ty| visit(ast, ty, visited)),
            Optional(inner) => visit(ast, inner, visited),
            _ => false,
        }
    }
    visit(ast, ty, &mut HashSet::new())
}


================================================
FILE: src/swift.rs
================================================
use super::*;
use std::borrow::Cow;
use std::collections::{HashMap, HashSet};
use std::rc::Rc;

/// Use this target when the host language is Swift.
///
/// This needs to generate a `.swift` file and a `.h` file. By default, the
/// files will be named `miniffi.swift` and `miniffi.h` and will be written to
/// the directory containing your `Cargo.toml` file. You can customize these
/// paths before calling [`build`](Target::build):
///
/// ```no_run
/// use miniffi::*;
///
/// fn main() {
///     SwiftTarget::new()
///         .write_swift_to("../app/rust.swift")
///         .write_header_to("../app/rust.h")
///         .build();
/// }
/// ```
///
/// If your `src/lib.rs` looks like this:
///
/// ```no_run
/// pub fn add(left: u64, right: u64) -> u64 {
///     left + right
/// }
///
/// # macro_rules! env { ($a:expr) => { $a } }
/// # macro_rules! include { ($a:expr) => { $a } }
/// include!(concat!(env!("OUT_DIR"), "/miniffi.rs"));
/// ```
///
/// You can call that from Swift like this:
///
/// ```text
/// print("1 + 2 =", add(1, 2))
/// ```
///
/// Even though Swift is the host language, the `.h` file is necessary because
/// Swift lacks syntax for specifying certain interactions with the C ABI that
/// Rust uses. Instead of building those features into Swift itself, Apple has
/// decided to make those features work by passing a C header to the Swift
/// compiler instead. This is called using an "Objective-C bridging header"
/// even though it has nothing to do with Objective-C in this case.
///
/// ## Using the command line
///
/// If you are using Swift from the command line, then you can call Rust from
/// Swift by adding the generated `.swift` file, passing the generated `.h`
/// file as the Objective-C bridging header, and also linking to the compiled
/// Rust code. For example:
///
/// ```text
/// # Build the Rust code
/// cargo rustc --crate-type=staticlib
///
/// # Build the Swift code
/// swiftc main.swift miniffi.swift -import-objc-header miniffi.h ./target/debug/libexample.a
/// ```
///
/// ## Using Xcode
///
/// If you're using Swift from Xcode, then the process is more complicated.
/// There are also various ways to do this. Here's the process I use:
///
/// 1. Create a `Makefile` to build your Rust code
///
///     Put the following in a file called `Makefile` in your Rust crate:
///
///     ```makefile
///     Debug:
///     	cargo rustc --crate-type=staticlib
///
///     Release:
///     	cargo rustc --crate-type=staticlib --release
///     ```
///
///     Using an additional script like this makes our life easier later since
///     we can reference it from the `xcodeproj` settings. Note that these
///     indents are intentionally tab characters, not spaces (`make` requires
///     tab characters).
///
/// 2. Tell Xcode to compile the generated code
///
///     Run `make` to cause the build script to run, which will generate
///     `miniffi.swift` and `miniffi.h`. Then in Xcode, add `miniffi.swift` and
///     `miniffi.h` to your project (make sure they are referenced, not copied).
///
///     Include `miniffi.h` in your Objective-C Bridging Header. If you already
///     have a bridging header, use `#include` to include `miniffi.h` there.
///     Otherwise you can go to the **Build Settings** tab in your `xcodeproj`
///     settings and set **Objective-C Bridging Header** directly to `miniffi.h`.
///
/// 3. Tell Xcode to link with the compiled Rust code
///
///     In the **Build Settings** tab of your `xcodeproj` settings, expand
///     **Library Search Paths** into separate **Debug** and **Release** rows.
///     Set the **Debug** path to `./target/debug` and the **Release** path to
///     `./target/release`.
///
///     Go to the **Build Phases** tab of your `xcodeproj` settings. Expand
///     **Link Binary With Libraries**, click the `+` button, click
///     **Add Other...** > **Add Files...**, and select the
///     `./target/debug/libexample.a` file that you built earlier.
///
///     At this point, you should now be able to compile and run your Xcode
///     project and call Rust from Swift! But there's one more step you'll
///     likely want to do...
///
/// 4. Tell Xcode to rebuild your Rust code automatically
///
///     In the **Build Settings** tab of your `xcodeproj` settings, set
///     **User Scripts Sandboxing** to No. We will be building your Rust code
///     which exists on the file system, so we need file system access.
///
///     Go to the **Build Phases** tab of your `xcodeproj` settings. Use the `+`
///     button to add a **New Run Script Phase** and drag it before the
///     **Compile Sources** phase. Expand it and use the following shell script:
///
///     ```sh
///     export PATH="$HOME/.cargo/bin:$PATH"
///     make "$CONFIGURATION"
///     ```
///
///     You can also uncheck the **Based on dependency analysis** checkbox to
///     disable an Xcode warning.
///
///     Using `$CONFIGURATION` in combination with the `Makefile` means the
///     **Debug** build configuration in Xcode will build your Rust code in debug
///     mode (without the `--release` flag), and the **Release** build
///     configuration in Xcode will build your rust code in release mode (with
///     the `--release` flag). The `export PATH` is necessary because Xcode
///     doesn't use your `$PATH` and won't be able to find the `cargo` binary
///     otherwise.
pub struct SwiftTarget {
    common_options: CommonOptions,
    swift_path: PathBuf,
    header_path: PathBuf,
}

impl SwiftTarget {
    pub fn new() -> SwiftTarget {
        SwiftTarget {
            common_options: CommonOptions::default(),
            swift_path: "miniffi.swift".into(),
            header_path: "miniffi.h".into(),
        }
    }

    pub fn write_swift_to<T: Into<PathBuf>>(mut self, path: T) -> Self {
        self.swift_path = path.into();
        self
    }

    pub fn write_header_to<T: Into<PathBuf>>(mut self, path: T) -> Self {
        self.header_path = path.into();
        self
    }
}

pub const SWIFT_KEYWORDS: &[&str] = &[
    "Any",
    "as",
    "associatedtype",
    "associativity",
    "async",
    "await",
    "borrowing",
    "break",
    "case",
    "catch",
    "catch",
    "class",
    "consuming",
    "continue",
    "convenience",
    "default",
    "defer",
    "deinit",
    "didSet",
    "do",
    "dynamic",
    "else",
    "enum",
    "extension",
    "fallthrough",
    "false",
    "fileprivate",
    "final",
    "for",
    "func",
    "get",
    "guard",
    "if",
    "import",
    "in",
    "indirect",
    "infix",
    "init",
    "inout",
    "internal",
    "is",
    "lazy",
    "left",
    "let",
    "mutating",
    "nil",
    "none",
    "nonisolated",
    "nonmutating",
    "open",
    "operator",
    "optional",
    "override",
    "package",
    "postfix",
    "precedence",
    "precedencegroup",
    "prefix",
    "private",
    "protocol",
    "Protocol",
    "public",
    "repeat",
    "required",
    "rethrows",
    "rethrows",
    "return",
    "right",
    "self",
    "Self",
    "set",
    "some",
    "static",
    "struct",
    "subscript",
    "super",
    "switch",
    "throw",
    "throw",
    "throws",
    "true",
    "try",
    "Type",
    "typealias",
    "unowned",
    "var",
    "weak",
    "where",
    "while",
    "willSet",
];

#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
enum HeaderGroup {
    Include,
    Other,
}

impl Compile for SwiftTarget {
    fn common_options(&mut self) -> &mut CommonOptions {
        &mut self.common_options
    }

    fn compile(&self, mut ast: AST, rust_path: PathBuf) -> Vec<FileData> {
        let syntax = RustSyntax::with_edition(self.common_options.edition);
        let mut rust_helpers = HelperSet::<(), String>::default();
        let mut swift_helpers = HelperSet::<(), String>::default();
        let mut header_helpers = HelperSet::<HeaderGroup, String>::default();

        // Also need to escape C++ keywords for the Objective-C bridging header
        let all_keywords: Vec<_> = SWIFT_KEYWORDS
            .iter()
            .chain(cpp::CPP_KEYWORDS.iter())
            .map(|x| *x)
            .collect();

        add_common_rust_helpers(&syntax, &mut rust_helpers);
        ast.rename_keywords(&all_keywords);

        header_helpers.add_group(
            HeaderGroup::Include,
            "<stdint.h>",
            "\n#include <stdint.h>\n",
        );

        header_helpers
            .add_group(
                HeaderGroup::Other,
                "_ffi_alloc",
                "\nvoid* _ffi_alloc(intptr_t len);\n",
            )
            .add_dep_group(HeaderGroup::Include, "<stdint.h>");

        header_helpers
            .add_group(
                HeaderGroup::Other,
                "_ffi_dealloc",
                "\nvoid _ffi_dealloc(const void* ptr, uintptr_t capacity);\n",
            )
            .add_dep_group(HeaderGroup::Include, "<stdint.h>");

        swift_helpers.add(
            "_ffi_read",
            r#"
private func _ffi_read<T>(_ ptr: inout UnsafeRawPointer) -> T {
    let val = ptr.loadUnaligned(fromByteOffset: 0, as: T.self)
    ptr = ptr.advanced(by: MemoryLayout<T>.size)
    return val
}
"#,
        );

        swift_helpers.add(
            "_ffi_write",
            r#"
private func _ffi_write<T>(_ val: T, _ buf: inout ContiguousArray<UInt8>) {
    var val = val
    withUnsafeBytes(of: &val) { val in
        buf.append(contentsOf: val)
    }
}
"#,
        );

        swift_helpers.add(
            "_ffi_swift_drop",
            r#"
@_cdecl("_ffi_swift_drop")
func _ffi_swift_drop(ptr: UnsafeRawPointer?) {
    _ = Unmanaged<AnyObject>.fromOpaque(ptr!).takeRetainedValue()
}
"#,
        );

        swift_helpers.add(
            "_ffi_vec_to_rust",
            r"
private func _ffi_vec_to_rust(_ vec: ContiguousArray<UInt8>) -> UnsafeRawPointer? {
    vec.withUnsafeBytes { vec in
        let buf = UnsafeMutableRawBufferPointer(start: _ffi_alloc(vec.count), count: vec.count)
        buf.copyMemory(from: UnsafeRawBufferPointer(start: vec.baseAddress, count: vec.count))
        return UnsafeRawPointer(buf.baseAddress)
    }
}
",
        );

        swift_helpers.add(
            "_ffi_string_to_rust",
            r"
private func _ffi_string_to_rust(_ str: String) -> (UnsafeRawPointer?, UInt) {
    var str = str
    return str.withUTF8 { str in
        let buf = UnsafeMutableRawBufferPointer(start: _ffi_alloc(str.count), count: str.count)
        buf.copyMemory(from: UnsafeRawBufferPointer(start: str.baseAddress, count: str.count))
        return (UnsafeRawPointer(buf.baseAddress), UInt(buf.count))
    }
}
",
        );

        swift_helpers.add(
            "_ffi_string_from_rust",
            r"
private func _ffi_string_from_rust(_ ptr: UnsafeRawPointer?, _ len: Int, _ cap: UInt) -> String {
    let buf = UnsafeBufferPointer(start: ptr!.assumingMemoryBound(to: UInt8.self), count: len)
    let str = String(decoding: buf, as: UTF8.self)
    _ffi_dealloc(ptr, cap)
    return str
}
",
        );

        let mut rust = format!("// {DO_NOT_EDIT_COMMENT}\n");
        let mut swift = format!("// {DO_NOT_EDIT_COMMENT}\n");

        // Traits
        for t in &ast.traits {
            _ = write!(swift, "\nprotocol {}: AnyObject {{\n", t.name);
            for f in &t.fns {
                _ = write!(swift, "    func {}(", f.name);
                for (i, arg) in f.args.iter().enumerate() {
                    if i > 0 {
                        swift.push_str(", ");
                    }
                    _ = write!(swift, "_ {}: ", arg.name);
                    append_swift_type(&mut swift, &ast, &arg.ty);
                }
                swift.push(')');
                if let Some(returns) = &f.returns {
                    swift.push_str(" -> ");
                    append_swift_type(&mut swift, &ast, &returns.ty);
                }
                swift.push('\n');
            }
            swift.push_str("}\n");
        }

        // Enums
        for (i, e) in ast.enums.iter().enumerate() {
            if !e.has_fields() {
                // Enums without fields are just integers
                _ = write!(swift, "\nenum {}: Int32", e.name);
                swift.push_str(" {\n");
                for v in &e.variants {
                    _ = write!(swift, "    case {} = {}\n", v.name, v.discriminant);
                }
                swift.push_str("}\n");
            } else {
                // Enums with fields map directly to Swift enums
                _ = write!(swift, "\nenum {}", e.name);
                if e.derives_partial_eq {
                    swift.push_str(" : Equatable");
                }
                swift.push_str(" {\n");
                for v in &e.variants {
                    let indirect = match swift_variant_needs_indirect(&ast, i, v) {
                        false => "",
                        true => "indirect ",
                    };
                    _ = write!(swift, "    {indirect}case {}", v.name);
                    if !v.fields.is_empty() {
                        swift.push('(');
                        for (j, f) in v.fields.iter().enumerate() {
                            if j > 0 {
                                swift.push_str(", ");
                            }
                            if !starts_with_digit(&f.name) {
                                _ = write!(swift, "{}: ", f.name);
                            }
                            append_swift_type(&mut swift, &ast, &f.ty);
                        }
                        swift.push(')');
                    }
                    swift.push('\n');
                }
                if e.derives_partial_eq
                    && e.variants
                        .iter()
                        .any(|v| v.fields.iter().any(|f| swift_type_contains_tuple(&f.ty)))
                {
                    swift.push_str(&generate_operator_eq_enum(e));
                }
                swift.push_str("}\n");
            }
        }

        // Structs
        for (i, s) in ast.structs.iter().enumerate() {
            let use_class = swift_type_is_infinite_size(&ast, &RustType::Struct(i));
            let keyword = if use_class { "class" } else { "struct" };
            _ = write!(swift, "\n{keyword} {}", s.name);
            if s.derives_partial_eq {
                swift.push_str(" : Equatable");
            }
            swift.push_str(" {\n");
            for f in &s.fields {
                _ = write!(swift, "    var {}: ", with_digit_prefix(&f.name));
                append_swift_type(&mut swift, &ast, &f.ty);
                swift.push('\n');
            }
            if use_class {
                swift.push_str(&generate_init(&ast, s));
            }
            if s.derives_partial_eq
                && (use_class || s.fields.iter().any(|f| swift_type_contains_tuple(&f.ty)))
            {
                swift.push_str(&generate_operator_eq_struct(s));
            }
            swift.push_str("}\n");
        }

        // Constants
        if !ast.consts.is_empty() {
            swift.push('\n');
            for c in &ast.consts {
                _ = write!(swift, "let {}: ", c.name);
                append_swift_type(&mut swift, &ast, &c.ty);
                swift.push_str(" = ");
                append_swift_val(&mut swift, &c.val);
                swift.push('\n');
            }
        }

        let mut ctx = SwiftCtx {
            syntax,
            rust_helpers,
            swift_helpers,
            header_helpers,
            ..SwiftCtx::default()
        };

        // Functions
        for f in &ast.fns {
            generate_swift_to_rust_fn(&ast, &mut ctx, f, &mut swift, None);
        }

        for it in ctx.rust_helpers.code_in_order() {
            rust.push_str(it);
        }

        for it in ctx.swift_helpers.code_in_order() {
            swift.push_str(it);
        }

        let header_code = ctx.header_helpers.code_by_group_in_order();
        let mut header = format!("// {DO_NOT_EDIT_COMMENT}\n");
        header.push_str("\n#pragma once\n");

        if let Some(code) = header_code.get(&HeaderGroup::Include) {
            for it in code {
                header.push_str(it);
            }
        }

        header.push_str("\n#ifdef __cplusplus\n");
        header.push_str("extern \"C\" {\n");
        header.push_str("#endif\n");

        if let Some(code) = header_code.get(&HeaderGroup::Other) {
            for it in code {
                header.push_str(it);
            }
        }

        header.push_str("\n#ifdef __cplusplus\n");
        header.push_str("}\n");
        header.push_str("#endif\n");

        vec![
            FileData {
                path: rust_path,
                contents: rust,
            },
            FileData {
                path: self.swift_path.clone(),
                contents: swift,
            },
            FileData {
                path: self.header_path.clone(),
                contents: header,
            },
        ]
    }
}

fn swift_type_contains_tuple(ty: &RustType) -> bool {
    use RustType::*;
    match ty {
        Pair { other, .. } => swift_type_contains_tuple(other),
        Vector(inner_ty) => swift_type_contains_tuple(inner_ty),
        Optional(inner_ty) => swift_type_contains_tuple(inner_ty),
        Ptr(_, inner_ty) => swift_type_contains_tuple(inner_ty),
        Tuple(types) => types.len() != 1,
        _ => false,
    }
}

fn generate_init(ast: &AST, s: &RustStruct) -> String {
    let mut swift = "\n    init(".to_string();
    for (i, f) in s.fields.iter().enumerate() {
        if i > 0 {
            swift.push_str(", ");
        }
        swift.push_str(&f.name);
        swift.push_str(": ");
        append_swift_type(&mut swift, ast, &f.ty);
    }
    swift.push_str(") {\n");
    for f in &s.fields {
        _ = write!(swift, "        self.{} = {}\n", f.name, f.name);
    }
    swift.push_str("    }\n");
    swift
}

fn emit_eq(parts: &mut Vec<String>, ty: &RustType, a: &str, b: &str) {
    use RustType::*;

    if !swift_type_contains_tuple(ty) {
        parts.push(format!("{a} == {b}"));
        return;
    }

    match ty {
        Pair { other, .. } => emit_eq(parts, other, a, b),
        Ptr(_, inner_ty) => emit_eq(parts, inner_ty, a, b),

        // Unfortunately tuples in Swift don't currently implement
        // "Equatable", so structs containing tuples cannot automatically
        // derive "Equatable". There have been many attempts to fix this
        // but somehow it's still broken? Works fine in other languages.
        // Gotta work around it ourselves...
        Tuple(types) if types.len() != 1 => {
            for (i, ty) in types.iter().enumerate() {
                let a = format!("{a}.{i}");
                let b = format!("{b}.{i}");
                emit_eq(parts, ty, &a, &b);
            }
        }

        Optional(inner_ty) => {
            let mut inner_parts = Vec::new();
            emit_eq(&mut inner_parts, inner_ty, "a", "b");
            parts.push(if inner_parts.is_empty() {
                    format!("({a} != nil) == ({b} != nil)")
                } else {
                    format!(
                        "{{ if let a = {a}, let b = {b} {{ {} }} else {{ {a} == nil && {b} == nil }} }}()",
                        inner_parts.join(" && ")
                    )
                });
        }

        Vector(inner_ty) => {
            let mut inner_parts = Vec::new();
            emit_eq(&mut inner_parts, inner_ty, "a", "b");
            parts.push(if inner_parts.is_empty() {
                format!("{a}.count == {b}.count")
            } else {
                format!(
                    "{a}.elementsEqual({b}, by: {{ a, b in {} }})",
                    inner_parts.join(" && ")
                )
            });
        }

        _ => parts.push(format!("{a} == {b}")),
    }
}

fn emit_eq_return(parts: &[String], base_indent: &str) -> String {
    if parts.is_empty() {
        "return true".to_string()
    } else if parts.len() == 1 || parts.iter().map(|x| x.len()).sum::<usize>() < 100 {
        format!("return {}", parts.join(" && "))
    } else {
        let mut swift = "return (".to_string();
        for (i, part) in parts.iter().enumerate() {
            if i > 0 {
                swift.push_str(" &&");
            }
            _ = write!(swift, "\n{base_indent}    {part}");
        }
        _ = write!(swift, "\n{base_indent})");
        swift
    }
}

fn generate_operator_eq_struct(s: &RustStruct) -> String {
    let mut swift = String::new();
    let mut parts = Vec::new();

    for f in &s.fields {
        let name = with_digit_prefix(&f.name);
        let a = format!("a.{}", name);
        let b = format!("b.{}", name);
        emit_eq(&mut parts, &f.ty, &a, &b);
    }

    _ = write!(
        swift,
        "\n    static func == (a: {}, b: {}) -> Bool {{\n",
        s.name, s.name
    );
    _ = 
Download .txt
gitextract_elwbkvg6/

├── Cargo.toml
├── LICENSE.md
├── README.md
└── src/
    ├── ast.rs
    ├── cpp.rs
    ├── lib.rs
    ├── rust.rs
    ├── scan.rs
    ├── swift.rs
    ├── tests/
    │   ├── cases/
    │   │   ├── demo_app.rs
    │   │   ├── demo_const.rs
    │   │   ├── demo_derive_eq.rs
    │   │   ├── demo_enum.rs
    │   │   ├── demo_keyword.rs
    │   │   ├── demo_order.rs
    │   │   ├── demo_trait.rs
    │   │   ├── fn_basic.rs
    │   │   ├── fn_basic_void.rs
    │   │   ├── fn_box_in.rs
    │   │   ├── fn_box_out.rs
    │   │   ├── fn_combo_in.rs
    │   │   ├── fn_combo_out.rs
    │   │   ├── fn_enum_in.rs
    │   │   ├── fn_enum_out.rs
    │   │   ├── fn_nested_in.rs
    │   │   ├── fn_nested_out.rs
    │   │   ├── fn_option_in.rs
    │   │   ├── fn_option_out.rs
    │   │   ├── fn_payload_in.rs
    │   │   ├── fn_payload_out.rs
    │   │   ├── fn_string.rs
    │   │   ├── fn_struct_in.rs
    │   │   ├── fn_struct_out.rs
    │   │   ├── fn_tuple_in.rs
    │   │   ├── fn_tuple_out.rs
    │   │   ├── fn_vec_in.rs
    │   │   ├── fn_vec_out.rs
    │   │   ├── mod.rs
    │   │   ├── trait_enum.rs
    │   │   ├── trait_export.rs
    │   │   ├── trait_export_import.rs
    │   │   ├── trait_export_nested.rs
    │   │   ├── trait_import.rs
    │   │   ├── trait_import_export.rs
    │   │   ├── trait_import_nested.rs
    │   │   ├── trait_import_struct_in.rs
    │   │   ├── trait_import_tuple_in.rs
    │   │   └── trait_string.rs
    │   ├── cpp.rs
    │   ├── mod.rs
    │   ├── snapshots/
    │   │   ├── cpp_demo_app_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_demo_app_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_demo_const_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_demo_const_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_demo_derive_eq_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_demo_derive_eq_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_demo_enum_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_demo_enum_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_demo_keyword_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_demo_keyword_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_demo_order_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_demo_order_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_demo_trait_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_demo_trait_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_basic_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_basic_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_basic_void_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_basic_void_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_box_in_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_box_in_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_box_out_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_box_out_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_combo_in_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_combo_in_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_combo_out_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_combo_out_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_enum_in_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_enum_in_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_enum_out_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_enum_out_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_nested_in_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_nested_in_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_nested_out_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_nested_out_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_option_in_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_option_in_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_option_out_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_option_out_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_payload_in_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_payload_in_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_payload_out_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_payload_out_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_string_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_string_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_struct_in_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_struct_in_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_struct_out_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_struct_out_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_tuple_in_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_tuple_in_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_tuple_out_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_tuple_out_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_vec_in_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_vec_in_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_vec_out_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_fn_vec_out_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_trait_enum_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_trait_enum_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_trait_export_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_trait_export_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_trait_export_import_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_trait_export_import_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_trait_export_nested_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_trait_export_nested_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_trait_import_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_trait_import_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_trait_import_export_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_trait_import_export_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_trait_import_nested_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_trait_import_nested_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_trait_import_struct_in_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_trait_import_struct_in_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_trait_import_tuple_in_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_trait_import_tuple_in_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_trait_string_2021/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── cpp_trait_string_2024/
    │   │   │   ├── ffi.cpp
    │   │   │   ├── ffi.h
    │   │   │   └── miniffi.rs
    │   │   ├── swift_demo_app_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_demo_app_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_demo_const_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_demo_const_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_demo_derive_eq_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_demo_derive_eq_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_demo_enum_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_demo_enum_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_demo_keyword_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_demo_keyword_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_demo_order_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_demo_order_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_demo_trait_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_demo_trait_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_basic_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_basic_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_basic_void_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_basic_void_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_box_in_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_box_in_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_box_out_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_box_out_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_combo_in_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_combo_in_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_combo_out_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_combo_out_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_enum_in_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_enum_in_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_enum_out_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_enum_out_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_nested_in_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_nested_in_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_nested_out_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_nested_out_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_option_in_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_option_in_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_option_out_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_option_out_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_payload_in_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_payload_in_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_payload_out_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_payload_out_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_string_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_string_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_struct_in_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_struct_in_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_struct_out_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_struct_out_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_tuple_in_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_tuple_in_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_tuple_out_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_tuple_out_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_vec_in_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_vec_in_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_vec_out_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_fn_vec_out_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_trait_enum_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_trait_enum_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_trait_export_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_trait_export_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_trait_export_import_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_trait_export_import_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_trait_export_nested_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_trait_export_nested_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_trait_import_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_trait_import_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_trait_import_export_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_trait_import_export_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_trait_import_nested_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_trait_import_nested_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_trait_import_struct_in_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_trait_import_struct_in_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_trait_import_tuple_in_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_trait_import_tuple_in_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_trait_string_2021/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── swift_trait_string_2024/
    │   │   │   ├── ffi.h
    │   │   │   ├── ffi.swift
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_demo_app_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_demo_app_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_demo_const_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_demo_const_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_demo_derive_eq_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_demo_derive_eq_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_demo_enum_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_demo_enum_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_demo_keyword_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_demo_keyword_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_demo_order_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_demo_order_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_demo_trait_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_demo_trait_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_basic_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_basic_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_basic_void_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_basic_void_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_box_in_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_box_in_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_box_out_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_box_out_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_combo_in_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_combo_in_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_combo_out_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_combo_out_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_enum_in_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_enum_in_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_enum_out_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_enum_out_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_nested_in_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_nested_in_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_nested_out_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_nested_out_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_option_in_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_option_in_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_option_out_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_option_out_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_payload_in_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_payload_in_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_payload_out_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_payload_out_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_string_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_string_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_struct_in_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_struct_in_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_struct_out_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_struct_out_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_tuple_in_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_tuple_in_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_tuple_out_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_tuple_out_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_vec_in_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_vec_in_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_vec_out_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_fn_vec_out_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_trait_enum_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_trait_enum_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_trait_export_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_trait_export_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_trait_export_import_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_trait_export_import_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_trait_export_nested_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_trait_export_nested_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_trait_import_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_trait_import_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_trait_import_export_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_trait_import_export_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_trait_import_nested_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_trait_import_nested_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_trait_import_struct_in_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_trait_import_struct_in_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_trait_import_tuple_in_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_trait_import_tuple_in_2024/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   ├── wasm_trait_string_2021/
    │   │   │   ├── ffi.d.mts
    │   │   │   ├── ffi.mjs
    │   │   │   ├── ffi.mts
    │   │   │   └── miniffi.rs
    │   │   └── wasm_trait_string_2024/
    │   │       ├── ffi.d.mts
    │   │       ├── ffi.mjs
    │   │       ├── ffi.mts
    │   │       └── miniffi.rs
    │   ├── swift.rs
    │   ├── warnings.rs
    │   └── wasm.rs
    ├── util.rs
    └── wasm.rs
Download .txt
Showing preview only (552K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (5666 symbols across 525 files)

FILE: src/ast.rs
  type AST (line 5) | pub struct AST {
    method rename_keywords (line 14) | pub fn rename_keywords(&mut self, keywords: &[&str]) {
  type RustStruct (line 57) | pub struct RustStruct {
  type RustEnum (line 63) | pub struct RustEnum {
    method has_fields (line 70) | pub fn has_fields(&self) -> bool {
  type RustVariant (line 75) | pub struct RustVariant {
  type RustTrait (line 81) | pub struct RustTrait {
  type RustField (line 87) | pub struct RustField {
  type RustConst (line 92) | pub struct RustConst {
  type RustFn (line 98) | pub struct RustFn {
  type RustArg (line 105) | pub struct RustArg {
  type RustPtr (line 111) | pub enum RustPtr {
    method path (line 117) | pub fn path(&self) -> &'static str {
  type RustType (line 126) | pub enum RustType {
  type RustVal (line 164) | pub enum RustVal {
  function append_type_name_hint (line 183) | pub fn append_type_name_hint(out: &mut String, ast: &AST, ty: &RustType) {
  function append_type_name_hints (line 247) | pub fn append_type_name_hints(out: &mut String, ast: &AST, types: &[Rust...

FILE: src/cpp.rs
  type CppTarget (line 172) | pub struct CppTarget {
    method new (line 180) | pub fn new() -> CppTarget {
    method write_source_to (line 189) | pub fn write_source_to<T: Into<PathBuf>>(mut self, path: T) -> Self {
    method write_header_to (line 194) | pub fn write_header_to<T: Into<PathBuf>>(mut self, path: T) -> Self {
  constant CPP_KEYWORDS (line 200) | pub const CPP_KEYWORDS: &[&str] = &[
  type HeaderGroup (line 302) | enum HeaderGroup {
  type SourceGroup (line 310) | enum SourceGroup {
  method common_options (line 320) | fn common_options(&mut self) -> &mut CommonOptions {
  method compile (line 324) | fn compile(&self, mut ast: AST, rust_path: PathBuf) -> Vec<FileData> {
  function cpp_struct_field_init (line 801) | fn cpp_struct_field_init(ast: &AST, ty: &RustType) -> &'static str {
  type CppCtx (line 814) | struct CppCtx {
  type Transform (line 833) | struct Transform {
  type TraitInfo (line 842) | struct TraitInfo<'a> {
  function self_type (line 848) | fn self_type(&self, ns: &str) -> RustType {
  function cpp_name (line 855) | fn cpp_name(&self) -> String {
  function generate_cpp_to_rust_fn (line 860) | fn generate_cpp_to_rust_fn(
  function generate_rust_to_cpp_fn (line 1108) | fn generate_rust_to_cpp_fn(
  function generate_operator_eq (line 1295) | fn generate_operator_eq(
  function transform_to_rust (line 1444) | fn transform_to_rust(
  function transform_to_cpp (line 1689) | fn transform_to_cpp(
  function ensure_cpp_buf (line 1977) | fn ensure_cpp_buf(
  function ensure_rust_buf (line 2019) | fn ensure_rust_buf(
  function vec_to_rust_helper (line 2071) | fn vec_to_rust_helper(ast: &AST, ctx: &mut CppCtx, inner_ty: &RustType) ...
  function vec_to_cpp_helper (line 2178) | fn vec_to_cpp_helper(ast: &AST, ctx: &mut CppCtx, inner_ty: &RustType) -...
  function trait_to_rust_helper (line 2285) | fn trait_to_rust_helper(ast: &AST, ctx: &mut CppCtx, trait_index: usize,...
  function trait_to_cpp_helper (line 2356) | fn trait_to_cpp_helper(ast: &AST, ctx: &mut CppCtx, trait_index: usize, ...
  function box_to_rust_helper (line 2444) | fn box_to_rust_helper(ast: &AST, ctx: &mut CppCtx, inner_ty: &RustType) ...
  function box_to_cpp_helper (line 2542) | fn box_to_cpp_helper(ast: &AST, ctx: &mut CppCtx, inner_ty: &RustType) -...
  function enum_to_rust_helper (line 2638) | fn enum_to_rust_helper(ast: &AST, ctx: &mut CppCtx, enum_index: usize) -...
  function enum_to_cpp_helper (line 2828) | fn enum_to_cpp_helper(ast: &AST, ctx: &mut CppCtx, enum_index: usize) ->...
  function multi_ret_helper (line 3015) | fn multi_ret_helper(ast: &AST, ctx: &mut CppCtx, args: &[RustArg]) -> St...
  type CppDecl (line 3109) | enum CppDecl {
  type DeclGroups (line 3114) | struct DeclGroups<G: Clone + Copy> {
  function select (line 3120) | fn select(&self, decl: CppDecl) -> G {
  type TypeLoc (line 3129) | enum TypeLoc {
  type CppTypeCtx (line 3135) | struct CppTypeCtx<'a, G: Clone + Copy + Eq + Hash> {
  function append_cpp_signature (line 3146) | fn append_cpp_signature(
  function append_cpp_type (line 3182) | fn append_cpp_type(&mut self, ty: &RustType, decl: CppDecl) {
  function append_cpp_val (line 3320) | fn append_cpp_val(cpp: &mut String, val: &RustVal) {
  function append_cpp_quoted (line 3360) | fn append_cpp_quoted(cpp: &mut String, text: &str) {
  method write_to_cpp (line 3379) | fn write_to_cpp(

FILE: src/lib.rs
  constant DO_NOT_EDIT_COMMENT (line 111) | const DO_NOT_EDIT_COMMENT: &str = concat!(
  type Target (line 128) | pub trait Target {
    method build (line 154) | fn build(&self) -> BuildResult {
    method build_custom (line 196) | fn build_custom(&self, input_file: FileData, output_path: PathBuf) -> ...
    method rust_edition (line 200) | fn rust_edition(self, year: usize) -> Self;
    method rust_edition (line 399) | fn rust_edition(mut self, year: usize) -> Self {
    method build_custom (line 404) | fn build_custom(&self, input_file: FileData, output_path: PathBuf) -> ...
  type BuildResult (line 217) | pub struct BuildResult {
    method convert_warnings_to_errors (line 247) | pub fn convert_warnings_to_errors(mut self) -> Self {
    method finish (line 260) | pub fn finish(&mut self) {
  method drop (line 307) | fn drop(&mut self) {
  type Warning (line 316) | pub struct Warning {
    method to_short_string (line 333) | pub fn to_short_string(&self) -> String {
    method to_human_string (line 358) | pub fn to_human_string(&self) -> String {
  type FileData (line 378) | pub struct FileData {
  type CommonOptions (line 383) | struct CommonOptions {
  method default (line 388) | fn default() -> CommonOptions {
  type Compile (line 393) | trait Compile {
    method common_options (line 394) | fn common_options(&mut self) -> &mut CommonOptions;
    method compile (line 395) | fn compile(&self, ast: AST, rust_path: PathBuf) -> Vec<FileData>;
    method common_options (line 473) | fn common_options(&mut self) -> &mut CommonOptions {
    method compile (line 477) | fn compile(&self, _ast: AST, rust_path: PathBuf) -> Vec<FileData> {
  type NullTarget (line 460) | pub struct NullTarget {
    method new (line 465) | pub fn new() -> NullTarget {
  function write_file (line 485) | fn write_file(path: &Path, contents: &str, errors: &mut Vec<String>) {

FILE: src/rust.rs
  type RustSyntax (line 5) | pub struct RustSyntax {
    method with_edition (line 10) | pub fn with_edition(edition: usize) -> RustSyntax {
    method unsafe_no_mangle (line 14) | pub fn unsafe_no_mangle(&self) -> &'static str {
    method unsafe_extern (line 22) | pub fn unsafe_extern(&self) -> &'static str {
  function append_rust_type (line 31) | pub fn append_rust_type(rust: &mut String, ast: &AST, ty: &RustType) {
  function append_rust_default_val (line 100) | pub fn append_rust_default_val(rust: &mut String, ast: &AST, ty: &RustTy...
  method write_to_rust (line 151) | pub fn write_to_rust(&mut self, ast: &AST, out: &mut String, base_indent...
  function is_snake_case (line 186) | pub fn is_snake_case(name: &str) -> bool {
  function is_camel_case (line 191) | pub fn is_camel_case(name: &str) -> bool {
  function allow_non_snake_case (line 202) | pub fn allow_non_snake_case(rust: &mut String, name: &str) {
  function allow_non_camel_case_types (line 208) | pub fn allow_non_camel_case_types(rust: &mut String, name: &str) {
  function rust_decl_ctor (line 214) | pub fn rust_decl_ctor(
  function add_common_rust_helpers (line 248) | pub fn add_common_rust_helpers(syntax: &RustSyntax, helpers: &mut Helper...

FILE: src/scan.rs
  function scan_ast (line 5) | pub fn scan_ast(file: &FileData, parsed: &syn::File, warnings: &mut Vec<...
  function derives_partial_eq (line 216) | fn derives_partial_eq(attrs: &[Attribute]) -> bool {
  function parse_fields (line 236) | fn parse_fields(
  function to_rust_fn (line 285) | fn to_rust_fn(
  function to_rust_type (line 393) | fn to_rust_type(ast: &AST, ty: &syn::Type) -> Option<RustType> {
  function to_rust_val (line 500) | fn to_rust_val(expr: &syn::Expr, ty: &RustType) -> Option<RustVal> {
  function expr_to_numeric_literal (line 588) | fn expr_to_numeric_literal<T>(expr: &syn::Expr) -> Option<T>
  function path_to_string_with_argument (line 617) | fn path_to_string_with_argument(ast: &AST, path: &syn::Path) -> Option<(...
  function type_to_single_ident (line 644) | fn type_to_single_ident(ty: &syn::Type) -> Option<&syn::Ident> {
  function type_to_single_ident_with_argument (line 651) | fn type_to_single_ident_with_argument(ast: &AST, ty: &syn::Type) -> Opti...
  function pat_to_single_ident (line 658) | fn pat_to_single_ident(pat: &syn::Pat) -> Option<String> {
  function unsupported (line 666) | fn unsupported(
  function make_warning (line 685) | pub fn make_warning(
  function is_infinite_size (line 719) | fn is_infinite_size(ast: &AST, ty: &RustType) -> bool {

FILE: src/swift.rs
  type SwiftTarget (line 138) | pub struct SwiftTarget {
    method new (line 145) | pub fn new() -> SwiftTarget {
    method write_swift_to (line 153) | pub fn write_swift_to<T: Into<PathBuf>>(mut self, path: T) -> Self {
    method write_header_to (line 158) | pub fn write_header_to<T: Into<PathBuf>>(mut self, path: T) -> Self {
  constant SWIFT_KEYWORDS (line 164) | pub const SWIFT_KEYWORDS: &[&str] = &[
  type HeaderGroup (line 258) | enum HeaderGroup {
  method common_options (line 264) | fn common_options(&mut self) -> &mut CommonOptions {
  method compile (line 268) | fn compile(&self, mut ast: AST, rust_path: PathBuf) -> Vec<FileData> {
  function swift_type_contains_tuple (line 551) | fn swift_type_contains_tuple(ty: &RustType) -> bool {
  function generate_init (line 563) | fn generate_init(ast: &AST, s: &RustStruct) -> String {
  function emit_eq (line 581) | fn emit_eq(parts: &mut Vec<String>, ty: &RustType, a: &str, b: &str) {
  function emit_eq_return (line 636) | fn emit_eq_return(parts: &[String], base_indent: &str) -> String {
  function generate_operator_eq_struct (line 654) | fn generate_operator_eq_struct(s: &RustStruct) -> String {
  function generate_operator_eq_enum (line 676) | fn generate_operator_eq_enum(e: &RustEnum) -> String {
  type SwiftCtx (line 746) | struct SwiftCtx {
  type Transform (line 764) | struct Transform {
  type TraitInfo (line 773) | struct TraitInfo<'a> {
  function generate_swift_to_rust_fn (line 778) | fn generate_swift_to_rust_fn(
  function generate_rust_to_swift_fn (line 970) | fn generate_rust_to_swift_fn(
  function transform_to_rust (line 1151) | fn transform_to_rust(
  function transform_to_swift (line 1377) | fn transform_to_swift(
  function ensure_swift_buf (line 1629) | fn ensure_swift_buf(ctx: &mut SwiftCtx, names: &mut NameSet, tfm: &mut T...
  function ensure_rust_buf (line 1672) | fn ensure_rust_buf(ctx: &mut SwiftCtx, names: &mut NameSet, tfm: &mut Tr...
  function vec_to_rust_helper (line 1720) | fn vec_to_rust_helper(ast: &AST, ctx: &mut SwiftCtx, inner_ty: &RustType...
  function vec_to_swift_helper (line 1792) | fn vec_to_swift_helper(ast: &AST, ctx: &mut SwiftCtx, inner_ty: &RustTyp...
  function trait_to_rust_helper (line 1864) | fn trait_to_rust_helper(ast: &AST, ctx: &mut SwiftCtx, trait_index: usiz...
  function trait_to_swift_helper (line 1903) | fn trait_to_swift_helper(
  function box_to_rust_helper (line 1981) | fn box_to_rust_helper(ast: &AST, ctx: &mut SwiftCtx, inner_ty: &RustType...
  function box_to_swift_helper (line 2040) | fn box_to_swift_helper(ast: &AST, ctx: &mut SwiftCtx, inner_ty: &RustTyp...
  function enum_to_rust_helper (line 2099) | fn enum_to_rust_helper(ast: &AST, ctx: &mut SwiftCtx, enum_index: usize)...
  function enum_to_swift_helper (line 2244) | fn enum_to_swift_helper(ast: &AST, ctx: &mut SwiftCtx, enum_index: usize...
  function multi_ret_helper (line 2407) | fn multi_ret_helper(ast: &AST, ctx: &mut SwiftCtx, args: &[RustArg]) -> ...
  function append_swift_type (line 2453) | fn append_swift_type(swift: &mut String, ast: &AST, ty: &RustType) {
  function append_swift_val (line 2508) | fn append_swift_val(swift: &mut String, val: &RustVal) {
  function append_swift_quoted (line 2530) | fn append_swift_quoted(swift: &mut String, text: &str) {
  function append_c_signature (line 2546) | fn append_c_signature(
  function append_c_type (line 2581) | fn append_c_type(c: &mut String, deps: &mut HashSet<(HeaderGroup, String...
  function swift_type_is_infinite_size (line 2614) | fn swift_type_is_infinite_size(ast: &AST, ty: &RustType) -> bool {
  function swift_variant_needs_indirect (line 2640) | fn swift_variant_needs_indirect(ast: &AST, query_index: usize, v: &RustV...
  method write_to_swift (line 2686) | fn write_to_swift(&mut self, ast: &AST, out: &mut String, base_indent: &...

FILE: src/tests/cases/demo_app.rs
  function test_case (line 3) | fn test_case() -> TestCase {

FILE: src/tests/cases/demo_const.rs
  function test_case (line 3) | fn test_case() -> TestCase {

FILE: src/tests/cases/demo_derive_eq.rs
  function test_case (line 3) | fn test_case() -> TestCase {

FILE: src/tests/cases/demo_enum.rs
  function test_case (line 3) | fn test_case() -> TestCase {

FILE: src/tests/cases/demo_keyword.rs
  constant RUST_KEYWORDS (line 4) | const RUST_KEYWORDS: &[&str] = &[
  function test_case (line 12) | fn test_case() -> TestCase {

FILE: src/tests/cases/demo_order.rs
  function test_case (line 3) | fn test_case() -> TestCase {

FILE: src/tests/cases/demo_trait.rs
  function test_case (line 3) | fn test_case() -> TestCase {

FILE: src/tests/cases/fn_basic.rs
  function test_case (line 3) | fn test_case() -> TestCase {

FILE: src/tests/cases/fn_basic_void.rs
  function test_case (line 3) | fn test_case() -> TestCase {

FILE: src/tests/cases/fn_box_in.rs
  function test_case (line 3) | fn test_case() -> TestCase {

FILE: src/tests/cases/fn_box_out.rs
  function test_case (line 3) | fn test_case() -> TestCase {

FILE: src/tests/cases/fn_combo_in.rs
  function test_case (line 3) | fn test_case() -> TestCase {

FILE: src/tests/cases/fn_combo_out.rs
  function test_case (line 3) | fn test_case() -> TestCase {

FILE: src/tests/cases/fn_enum_in.rs
  function test_case (line 3) | fn test_case() -> TestCase {

FILE: src/tests/cases/fn_enum_out.rs
  function test_case (line 3) | fn test_case() -> TestCase {

FILE: src/tests/cases/fn_nested_in.rs
  function test_case (line 3) | fn test_case() -> TestCase {

FILE: src/tests/cases/fn_nested_out.rs
  function test_case (line 3) | fn test_case() -> TestCase {

FILE: src/tests/cases/fn_option_in.rs
  function test_case (line 3) | fn test_case() -> TestCase {

FILE: src/tests/cases/fn_option_out.rs
  function test_case (line 3) | fn test_case() -> TestCase {

FILE: src/tests/cases/fn_payload_in.rs
  function test_case (line 3) | fn test_case() -> TestCase {

FILE: src/tests/cases/fn_payload_out.rs
  function test_case (line 3) | fn test_case() -> TestCase {

FILE: src/tests/cases/fn_string.rs
  function test_case (line 3) | fn test_case() -> TestCase {

FILE: src/tests/cases/fn_struct_in.rs
  function test_case (line 3) | fn test_case() -> TestCase {

FILE: src/tests/cases/fn_struct_out.rs
  function test_case (line 3) | fn test_case() -> TestCase {

FILE: src/tests/cases/fn_tuple_in.rs
  function test_case (line 3) | fn test_case() -> TestCase {

FILE: src/tests/cases/fn_tuple_out.rs
  function test_case (line 3) | fn test_case() -> TestCase {

FILE: src/tests/cases/fn_vec_in.rs
  function test_case (line 3) | fn test_case() -> TestCase {

FILE: src/tests/cases/fn_vec_out.rs
  function test_case (line 3) | fn test_case() -> TestCase {

FILE: src/tests/cases/trait_enum.rs
  function test_case (line 3) | fn test_case() -> TestCase {

FILE: src/tests/cases/trait_export.rs
  function test_case (line 3) | fn test_case() -> TestCase {

FILE: src/tests/cases/trait_export_import.rs
  function test_case (line 3) | fn test_case() -> TestCase {

FILE: src/tests/cases/trait_export_nested.rs
  function test_case (line 3) | fn test_case() -> TestCase {

FILE: src/tests/cases/trait_import.rs
  function test_case (line 3) | fn test_case() -> TestCase {

FILE: src/tests/cases/trait_import_export.rs
  function test_case (line 3) | fn test_case() -> TestCase {

FILE: src/tests/cases/trait_import_nested.rs
  function test_case (line 3) | fn test_case() -> TestCase {

FILE: src/tests/cases/trait_import_struct_in.rs
  function test_case (line 3) | fn test_case() -> TestCase {

FILE: src/tests/cases/trait_import_tuple_in.rs
  function test_case (line 3) | fn test_case() -> TestCase {

FILE: src/tests/cases/trait_string.rs
  function test_case (line 3) | fn test_case() -> TestCase {

FILE: src/tests/cpp.rs
  function run_test (line 3) | pub fn run_test(name: &str, case: &TestCase, edition: usize) {
  function ty_to_str (line 206) | fn ty_to_str(ty: &ExprTy) -> String {
  function many_to_str (line 233) | fn many_to_str(x: &[Expr]) -> String {
  function to_str (line 237) | fn to_str(expr: &Expr) -> String {

FILE: src/tests/mod.rs
  type TestCase (line 56) | struct TestCase {
  type ExprTy (line 71) | enum ExprTy {
  type Expr (line 95) | enum Expr {
  function counter (line 141) | fn counter() -> &'static Mutex<usize> {
  function begin_test (line 145) | fn begin_test() {
  function end_test (line 150) | fn end_test() {
  function check_output (line 183) | fn check_output(output: Output) {
  function cargo_build (line 196) | fn cargo_build(test_dir: &Path, target: Option<&str>) {
  function copy_snapshot (line 223) | fn copy_snapshot(name: &str, from: PathBuf) {
  function rust_leak_check (line 235) | fn rust_leak_check() -> &'static str {

FILE: src/tests/snapshots/cpp_demo_app_2021/ffi.cpp
  type _ffi_ret_2_i32 (line 5) | struct _ffi_ret_2_i32 {
  type _ffi_ret_ptr_usize (line 10) | struct _ffi_ret_ptr_usize {
  function T (line 29) | T _ffi_read(const uint8_t* &ptr) {
  function _ffi_string_from_rust (line 36) | std::string _ffi_string_from_rust(const char* ptr, uintptr_t len, uintpt...
  function _ffi_vec_TextRun_from_rust (line 42) | std::vector<rust::TextRun> _ffi_vec_TextRun_from_rust(uintptr_t len, con...
  type _ffi_Box_Handler (line 61) | struct _ffi_Box_Handler final : rust::Handler {
    method _ffi_Box_Handler (line 62) | _ffi_Box_Handler(const void* ptr) : _self(ptr) {}
  function _ffi_cpp_Box_Canvas__draw_text_runs (line 77) | void _ffi_cpp_Box_Canvas__draw_text_runs(rust::Canvas* _self, const void...
  function _ffi_ret_2_i32 (line 92) | _ffi_ret_2_i32 _ffi_cpp_Rc_Window__get_size(std::shared_ptr<rust::Window...
  function _ffi_ret_ptr_usize (line 99) | _ffi_ret_ptr_usize _ffi_cpp_Rc_Window__get_title(std::shared_ptr<rust::W...
  function _ffi_cpp_Rc_Window__set_handler (line 105) | void _ffi_cpp_Rc_Window__set_handler(std::shared_ptr<rust::Window>* _sel...
  function _ffi_cpp_Rc_Window__set_size (line 110) | void _ffi_cpp_Rc_Window__set_size(std::shared_ptr<rust::Window>* _self, ...
  function _ffi_cpp_Rc_Window__set_title (line 114) | void _ffi_cpp_Rc_Window__set_title(std::shared_ptr<rust::Window>* _self,...
  function _ffi_cpp_drop_Box_Canvas (line 119) | void _ffi_cpp_drop_Box_Canvas(rust::Canvas* self) {
  function _ffi_cpp_drop_Box_Platform (line 123) | void _ffi_cpp_drop_Box_Platform(rust::Platform* self) {
  function _ffi_cpp_drop_Rc_Window (line 127) | void _ffi_cpp_drop_Rc_Window(std::shared_ptr<rust::Window>* self) {

FILE: src/tests/snapshots/cpp_demo_app_2021/ffi.h
  function namespace (line 11) | namespace rust {

FILE: src/tests/snapshots/cpp_demo_app_2021/miniffi.rs
  function _ffi_Box_Handler__on_draw (line 4) | extern "C" fn _ffi_Box_Handler__on_draw(_self: *const u8, canvas_ptr: *c...
  function _ffi_dealloc (line 10) | extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) {
  function _ffi_buf_to_host (line 14) | fn _ffi_buf_to_host(buf: Vec<u8>) -> (*const u8, usize) {
  function _ffi_drop_Box_Handler (line 20) | extern "C" fn _ffi_drop_Box_Handler(ptr: *const u8) {
  function _ffi_fn_create_app (line 25) | extern "C" fn _ffi_fn_create_app(platform_ptr: *const u8) {
  function _ffi_fn_rust_mem_leaked (line 30) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {
  type _ffi_ret_2_i32 (line 35) | struct _ffi_ret_2_i32(i32, i32);
  type _ffi_ret_ptr_usize (line 38) | struct _ffi_ret_ptr_usize(*const u8, usize);
  type _ffi_rs_Box_Canvas (line 41) | struct _ffi_rs_Box_Canvas(*const u8);
  method drop (line 44) | fn drop(&mut self) {
  method draw_text_runs (line 51) | fn draw_text_runs(&self, runs: Vec<TextRun>) {
  type _ffi_rs_Box_Platform (line 62) | struct _ffi_rs_Box_Platform(*const u8);
  method drop (line 65) | fn drop(&mut self) {
  method create_window (line 72) | fn create_window(&self) -> std::rc::Rc<dyn Window> {
  type _ffi_rs_Rc_Window (line 80) | struct _ffi_rs_Rc_Window(*const u8);
  method drop (line 83) | fn drop(&mut self) {
  method get_title (line 90) | fn get_title(&self) -> String {
  method set_title (line 98) | fn set_title(&self, title: &str) {
  method get_size (line 104) | fn get_size(&self) -> (i32, i32) {
  method set_size (line 112) | fn set_size(&self, width: i32, height: i32) {
  method set_handler (line 117) | fn set_handler(&self, handler: Box<dyn Handler>) {
  method child_window (line 122) | fn child_window(&self) -> std::rc::Rc<dyn Window> {
  function _ffi_alloc (line 130) | extern "C" fn _ffi_alloc(len: usize) -> *const u8 {
  function _ffi_string_from_host (line 134) | fn _ffi_string_from_host(ptr: *const u8, len: usize) -> String {
  function _ffi_string_to_host (line 138) | fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) {
  function _ffi_vec_TextRun_to_cpp (line 144) | fn _ffi_vec_TextRun_to_cpp(items: Vec<TextRun>, buf: &mut Vec<u8>) {
  function _ffi_write (line 157) | fn _ffi_write<T: Copy>(val: T, buf: &mut Vec<u8>) {

FILE: src/tests/snapshots/cpp_demo_app_2024/ffi.cpp
  type _ffi_ret_2_i32 (line 5) | struct _ffi_ret_2_i32 {
  type _ffi_ret_ptr_usize (line 10) | struct _ffi_ret_ptr_usize {
  function T (line 29) | T _ffi_read(const uint8_t* &ptr) {
  function _ffi_string_from_rust (line 36) | std::string _ffi_string_from_rust(const char* ptr, uintptr_t len, uintpt...
  function _ffi_vec_TextRun_from_rust (line 42) | std::vector<rust::TextRun> _ffi_vec_TextRun_from_rust(uintptr_t len, con...
  type _ffi_Box_Handler (line 61) | struct _ffi_Box_Handler final : rust::Handler {
    method _ffi_Box_Handler (line 62) | _ffi_Box_Handler(const void* ptr) : _self(ptr) {}
  function _ffi_cpp_Box_Canvas__draw_text_runs (line 77) | void _ffi_cpp_Box_Canvas__draw_text_runs(rust::Canvas* _self, const void...
  function _ffi_ret_2_i32 (line 92) | _ffi_ret_2_i32 _ffi_cpp_Rc_Window__get_size(std::shared_ptr<rust::Window...
  function _ffi_ret_ptr_usize (line 99) | _ffi_ret_ptr_usize _ffi_cpp_Rc_Window__get_title(std::shared_ptr<rust::W...
  function _ffi_cpp_Rc_Window__set_handler (line 105) | void _ffi_cpp_Rc_Window__set_handler(std::shared_ptr<rust::Window>* _sel...
  function _ffi_cpp_Rc_Window__set_size (line 110) | void _ffi_cpp_Rc_Window__set_size(std::shared_ptr<rust::Window>* _self, ...
  function _ffi_cpp_Rc_Window__set_title (line 114) | void _ffi_cpp_Rc_Window__set_title(std::shared_ptr<rust::Window>* _self,...
  function _ffi_cpp_drop_Box_Canvas (line 119) | void _ffi_cpp_drop_Box_Canvas(rust::Canvas* self) {
  function _ffi_cpp_drop_Box_Platform (line 123) | void _ffi_cpp_drop_Box_Platform(rust::Platform* self) {
  function _ffi_cpp_drop_Rc_Window (line 127) | void _ffi_cpp_drop_Rc_Window(std::shared_ptr<rust::Window>* self) {

FILE: src/tests/snapshots/cpp_demo_app_2024/ffi.h
  function namespace (line 11) | namespace rust {

FILE: src/tests/snapshots/cpp_demo_app_2024/miniffi.rs
  function _ffi_Box_Handler__on_draw (line 4) | extern "C" fn _ffi_Box_Handler__on_draw(_self: *const u8, canvas_ptr: *c...
  function _ffi_dealloc (line 10) | extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) {
  function _ffi_buf_to_host (line 14) | fn _ffi_buf_to_host(buf: Vec<u8>) -> (*const u8, usize) {
  function _ffi_drop_Box_Handler (line 20) | extern "C" fn _ffi_drop_Box_Handler(ptr: *const u8) {
  function _ffi_fn_create_app (line 25) | extern "C" fn _ffi_fn_create_app(platform_ptr: *const u8) {
  function _ffi_fn_rust_mem_leaked (line 30) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {
  type _ffi_ret_2_i32 (line 35) | struct _ffi_ret_2_i32(i32, i32);
  type _ffi_ret_ptr_usize (line 38) | struct _ffi_ret_ptr_usize(*const u8, usize);
  type _ffi_rs_Box_Canvas (line 41) | struct _ffi_rs_Box_Canvas(*const u8);
  method drop (line 44) | fn drop(&mut self) {
  method draw_text_runs (line 51) | fn draw_text_runs(&self, runs: Vec<TextRun>) {
  type _ffi_rs_Box_Platform (line 62) | struct _ffi_rs_Box_Platform(*const u8);
  method drop (line 65) | fn drop(&mut self) {
  method create_window (line 72) | fn create_window(&self) -> std::rc::Rc<dyn Window> {
  type _ffi_rs_Rc_Window (line 80) | struct _ffi_rs_Rc_Window(*const u8);
  method drop (line 83) | fn drop(&mut self) {
  method get_title (line 90) | fn get_title(&self) -> String {
  method set_title (line 98) | fn set_title(&self, title: &str) {
  method get_size (line 104) | fn get_size(&self) -> (i32, i32) {
  method set_size (line 112) | fn set_size(&self, width: i32, height: i32) {
  method set_handler (line 117) | fn set_handler(&self, handler: Box<dyn Handler>) {
  method child_window (line 122) | fn child_window(&self) -> std::rc::Rc<dyn Window> {
  function _ffi_alloc (line 130) | extern "C" fn _ffi_alloc(len: usize) -> *const u8 {
  function _ffi_string_from_host (line 134) | fn _ffi_string_from_host(ptr: *const u8, len: usize) -> String {
  function _ffi_string_to_host (line 138) | fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) {
  function _ffi_vec_TextRun_to_cpp (line 144) | fn _ffi_vec_TextRun_to_cpp(items: Vec<TextRun>, buf: &mut Vec<u8>) {
  function _ffi_write (line 157) | fn _ffi_write<T: Copy>(val: T, buf: &mut Vec<u8>) {

FILE: src/tests/snapshots/cpp_demo_const_2021/ffi.h
  function namespace (line 8) | namespace rust {

FILE: src/tests/snapshots/cpp_demo_const_2021/miniffi.rs
  function _ffi_fn_rust_mem_leaked (line 4) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {

FILE: src/tests/snapshots/cpp_demo_const_2024/ffi.h
  function namespace (line 8) | namespace rust {

FILE: src/tests/snapshots/cpp_demo_const_2024/miniffi.rs
  function _ffi_fn_rust_mem_leaked (line 4) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {

FILE: src/tests/snapshots/cpp_demo_derive_eq_2021/ffi.cpp
  type _ffi_ret_ptr_2_usize (line 7) | struct _ffi_ret_ptr_2_usize {
  type _ffi_ret_ptr_usize (line 13) | struct _ffi_ret_ptr_usize {
  type _ffi_ret_ptr_usize_bool (line 18) | struct _ffi_ret_ptr_usize_bool {
  function T (line 58) | T _ffi_read(const uint8_t* &ptr) {
  function _ffi_box_i32_i32_from_rust (line 65) | std::unique_ptr<std::tuple<int32_t, int32_t>> _ffi_box_i32_i32_from_rust...
  function _ffi_enum_EnumBoxTup_from_rust (line 72) | rust::EnumBoxTup _ffi_enum_EnumBoxTup_from_rust(const uint8_t*& end) {
  function _ffi_write (line 91) | void _ffi_write(T val, std::vector<uint8_t> &buf) {
  function _ffi_box_i32_i32_to_rust (line 95) | void _ffi_box_i32_i32_to_rust(std::tuple<int32_t, int32_t> val, std::vec...
  function _ffi_enum_EnumBoxTup_to_rust (line 100) | void _ffi_enum_EnumBoxTup_to_rust(rust::EnumBoxTup val, std::vector<uint...
  function _ffi_enum_EnumOptTup_from_rust (line 115) | rust::EnumOptTup _ffi_enum_EnumOptTup_from_rust(const uint8_t*& end) {
  function _ffi_enum_EnumOptTup_to_rust (line 138) | void _ffi_enum_EnumOptTup_to_rust(rust::EnumOptTup val, std::vector<uint...
  function _ffi_vec_i32_i32_from_rust (line 158) | std::vector<std::tuple<int32_t, int32_t>> _ffi_vec_i32_i32_from_rust(uin...
  function _ffi_enum_EnumVecTup_from_rust (line 170) | rust::EnumVecTup _ffi_enum_EnumVecTup_from_rust(const uint8_t*& end) {
  function _ffi_vec_i32_i32_to_rust (line 189) | void _ffi_vec_i32_i32_to_rust(std::vector<std::tuple<int32_t, int32_t>>&...
  function _ffi_enum_EnumVecTup_to_rust (line 196) | void _ffi_enum_EnumVecTup_to_rust(rust::EnumVecTup val, std::vector<uint...
  function _ffi_box_option_i32_from_rust (line 213) | std::unique_ptr<std::optional<int32_t>> _ffi_box_option_i32_from_rust(co...
  function _ffi_box_option_i32_to_rust (line 218) | void _ffi_box_option_i32_to_rust(std::optional<int32_t> val, std::vector...
  function _ffi_box_i32_from_rust2 (line 230) | std::unique_ptr<int32_t> _ffi_box_i32_from_rust2(const uint8_t*& end) {
  function _ffi_box_option_box_i32_from_rust (line 235) | std::unique_ptr<std::optional<std::unique_ptr<int32_t>>> _ffi_box_option...
  function _ffi_box_i32_to_rust2 (line 240) | void _ffi_box_i32_to_rust2(int32_t val, std::vector<uint8_t>& buf) {
  function _ffi_box_option_box_i32_to_rust (line 244) | void _ffi_box_option_box_i32_to_rust(std::optional<std::unique_ptr<int32...
  function _ffi_box__from_rust (line 252) | std::unique_ptr<std::tuple<>> _ffi_box__from_rust(const uint8_t*& end) {
  function _ffi_box__to_rust (line 257) | void _ffi_box__to_rust(std::tuple<> val, std::vector<uint8_t>& buf) {
  function _ffi_box_i32_from_rust (line 261) | std::unique_ptr<std::tuple<int32_t>> _ffi_box_i32_from_rust(const uint8_...
  function _ffi_box_i32_to_rust (line 267) | void _ffi_box_i32_to_rust(std::tuple<int32_t> val, std::vector<uint8_t>&...
  function _ffi_vec_i32_from_rust2 (line 271) | std::vector<int32_t> _ffi_vec_i32_from_rust2(uintptr_t len, const uint8_...
  function _ffi_box_vec_i32_from_rust (line 281) | std::unique_ptr<std::vector<int32_t>> _ffi_box_vec_i32_from_rust(const u...
  function _ffi_vec_i32_to_rust2 (line 287) | void _ffi_vec_i32_to_rust2(std::vector<int32_t>&& items, std::vector<uin...
  function _ffi_box_vec_i32_to_rust (line 293) | void _ffi_box_vec_i32_to_rust(std::vector<int32_t> val, std::vector<uint...
  function _ffi_vec_box_i32_from_rust (line 299) | std::vector<std::unique_ptr<int32_t>> _ffi_vec_box_i32_from_rust(uintptr...
  function _ffi_box_vec_box_i32_from_rust (line 309) | std::unique_ptr<std::vector<std::unique_ptr<int32_t>>> _ffi_box_vec_box_...
  function _ffi_vec_box_i32_to_rust (line 315) | void _ffi_vec_box_i32_to_rust(std::vector<std::unique_ptr<int32_t>>&& it...
  function _ffi_box_vec_box_i32_to_rust (line 321) | void _ffi_box_vec_box_i32_to_rust(std::vector<std::unique_ptr<int32_t>> ...
  function _ffi_box_bool_from_rust (line 327) | std::unique_ptr<bool> _ffi_box_bool_from_rust(const uint8_t*& end) {
  function _ffi_box_bool_to_rust (line 332) | void _ffi_box_bool_to_rust(bool val, std::vector<uint8_t>& buf) {
  function _ffi_vec_box_vec_i32_from_rust (line 336) | std::vector<std::unique_ptr<std::vector<int32_t>>> _ffi_vec_box_vec_i32_...
  function _ffi_vec_box_vec_i32_to_rust (line 346) | void _ffi_vec_box_vec_i32_to_rust(std::vector<std::unique_ptr<std::vecto...
  function _ffi_vec__from_rust (line 352) | std::vector<std::tuple<>> _ffi_vec__from_rust(uintptr_t len, const uint8...
  function _ffi_vec__to_rust (line 362) | void _ffi_vec__to_rust(std::vector<std::tuple<>>&& items, std::vector<ui...
  function _ffi_vec_i32_from_rust (line 368) | std::vector<std::tuple<int32_t>> _ffi_vec_i32_from_rust(uintptr_t len, c...
  function _ffi_vec_i32_to_rust (line 379) | void _ffi_vec_i32_to_rust(std::vector<std::tuple<int32_t>>&& items, std:...

FILE: src/tests/snapshots/cpp_demo_derive_eq_2021/ffi.h
  function namespace (line 12) | namespace rust {
  function namespace (line 61) | namespace detail {
  type EnumBoxTup__Baz (line 74) | struct EnumBoxTup__Baz {
  type EnumBoxTup (line 83) | struct EnumBoxTup
  function namespace (line 93) | namespace detail {
  type EnumOptTup__Baz (line 106) | struct EnumOptTup__Baz {
  type EnumOptTup (line 115) | struct EnumOptTup
  function namespace (line 125) | namespace detail {
  type EnumVecTup__Baz (line 138) | struct EnumVecTup__Baz {
  type EnumVecTup (line 147) | struct EnumVecTup
  type OptBox (line 157) | struct OptBox {
  type OptBoxOpt (line 163) | struct OptBoxOpt {
  type OptTup0 (line 169) | struct OptTup0 {
  type OptTup1 (line 175) | struct OptTup1 {
  type OptTup2 (line 181) | struct OptTup2 {
  type TupBox (line 187) | struct TupBox {
  type VecBox (line 193) | struct VecBox {
  type VecBoxVec (line 199) | struct VecBoxVec {
  type VecTup0 (line 205) | struct VecTup0 {
  type VecTup1 (line 211) | struct VecTup1 {
  type VecTup2 (line 217) | struct VecTup2 {

FILE: src/tests/snapshots/cpp_demo_derive_eq_2021/miniffi.rs
  function _ffi_box__from_cpp (line 4) | fn _ffi_box__from_cpp(_: &mut *const u8) -> Box<()> {
  function _ffi_box__to_cpp (line 9) | fn _ffi_box__to_cpp(val: (), _: &mut Vec<u8>) {
  function _ffi_box_bool_from_cpp (line 13) | fn _ffi_box_bool_from_cpp(end: &mut *const u8) -> Box<bool> {
  function _ffi_box_bool_to_cpp (line 17) | fn _ffi_box_bool_to_cpp(val: bool, buf: &mut Vec<u8>) {
  function _ffi_box_i32_from_cpp (line 21) | fn _ffi_box_i32_from_cpp(end: &mut *const u8) -> Box<(i32,)> {
  function _ffi_box_i32_from_cpp2 (line 25) | fn _ffi_box_i32_from_cpp2(end: &mut *const u8) -> Box<i32> {
  function _ffi_box_i32_i32_from_cpp (line 29) | fn _ffi_box_i32_i32_from_cpp(end: &mut *const u8) -> Box<(i32, i32)> {
  function _ffi_box_i32_i32_to_cpp (line 33) | fn _ffi_box_i32_i32_to_cpp(val: (i32, i32), buf: &mut Vec<u8>) {
  function _ffi_box_i32_to_cpp (line 38) | fn _ffi_box_i32_to_cpp(val: (i32,), buf: &mut Vec<u8>) {
  function _ffi_box_i32_to_cpp2 (line 42) | fn _ffi_box_i32_to_cpp2(val: i32, buf: &mut Vec<u8>) {
  function _ffi_box_option_box_i32_from_cpp (line 46) | fn _ffi_box_option_box_i32_from_cpp(end: &mut *const u8) -> Box<Option<B...
  function _ffi_box_option_box_i32_to_cpp (line 50) | fn _ffi_box_option_box_i32_to_cpp(val: Option<Box<i32>>, buf: &mut Vec<u...
  function _ffi_box_option_i32_from_cpp (line 57) | fn _ffi_box_option_i32_from_cpp(end: &mut *const u8) -> Box<Option<i32>> {
  function _ffi_box_option_i32_to_cpp (line 61) | fn _ffi_box_option_i32_to_cpp(val: Option<i32>, buf: &mut Vec<u8>) {
  function _ffi_box_vec_box_i32_from_cpp (line 68) | fn _ffi_box_vec_box_i32_from_cpp(end: &mut *const u8) -> Box<Vec<Box<i32...
  function _ffi_box_vec_box_i32_to_cpp (line 72) | fn _ffi_box_vec_box_i32_to_cpp(val: Vec<Box<i32>>, buf: &mut Vec<u8>) {
  function _ffi_box_vec_i32_from_cpp (line 77) | fn _ffi_box_vec_i32_from_cpp(end: &mut *const u8) -> Box<Vec<i32>> {
  function _ffi_box_vec_i32_to_cpp (line 81) | fn _ffi_box_vec_i32_to_cpp(val: Vec<i32>, buf: &mut Vec<u8>) {
  function _ffi_alloc (line 87) | extern "C" fn _ffi_alloc(len: usize) -> *const u8 {
  function _ffi_buf_from_host (line 91) | fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) {
  function _ffi_dealloc (line 97) | extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) {
  function _ffi_buf_to_host (line 101) | fn _ffi_buf_to_host(buf: Vec<u8>) -> (*const u8, usize) {
  function _ffi_read (line 106) | fn _ffi_read<T: Copy>(ptr: &mut *const u8) -> T {
  function _ffi_enum_EnumBoxTup_from_cpp (line 113) | fn _ffi_enum_EnumBoxTup_from_cpp(end: &mut *const u8) -> EnumBoxTup {
  function _ffi_write (line 122) | fn _ffi_write<T: Copy>(val: T, buf: &mut Vec<u8>) {
  function _ffi_enum_EnumBoxTup_to_cpp (line 129) | fn _ffi_enum_EnumBoxTup_to_cpp(val: EnumBoxTup, buf: &mut Vec<u8>) {
  function _ffi_enum_EnumOptTup_from_cpp (line 145) | fn _ffi_enum_EnumOptTup_from_cpp(end: &mut *const u8) -> EnumOptTup {
  function _ffi_enum_EnumOptTup_to_cpp (line 155) | fn _ffi_enum_EnumOptTup_to_cpp(val: EnumOptTup, buf: &mut Vec<u8>) {
  function _ffi_enum_EnumVecTup_from_cpp (line 175) | fn _ffi_enum_EnumVecTup_from_cpp(end: &mut *const u8) -> EnumVecTup {
  function _ffi_enum_EnumVecTup_to_cpp (line 185) | fn _ffi_enum_EnumVecTup_to_cpp(val: EnumVecTup, buf: &mut Vec<u8>) {
  function _ffi_fn_box_opt (line 202) | extern "C" fn _ffi_fn_box_opt(buf_ptr: *const u8) -> _ffi_ret_ptr_usize {
  function _ffi_fn_box_opt_box (line 214) | extern "C" fn _ffi_fn_box_opt_box(buf_ptr: *const u8) -> _ffi_ret_ptr_us...
  function _ffi_fn_box_tup_0 (line 226) | extern "C" fn _ffi_fn_box_tup_0(buf_ptr: *const u8) -> _ffi_ret_ptr_usize {
  function _ffi_fn_box_tup_1 (line 238) | extern "C" fn _ffi_fn_box_tup_1(buf_ptr: *const u8) -> _ffi_ret_ptr_usize {
  function _ffi_fn_box_tup_2 (line 250) | extern "C" fn _ffi_fn_box_tup_2(buf_ptr: *const u8) -> _ffi_ret_ptr_usize {
  function _ffi_fn_box_vec (line 262) | extern "C" fn _ffi_fn_box_vec(buf_ptr: *const u8) -> _ffi_ret_ptr_usize {
  function _ffi_fn_box_vec_box (line 274) | extern "C" fn _ffi_fn_box_vec_box(buf_ptr: *const u8) -> _ffi_ret_ptr_us...
  function _ffi_fn_empty_struct (line 286) | extern "C" fn _ffi_fn_empty_struct() {
  function _ffi_fn_empty_tuple (line 291) | extern "C" fn _ffi_fn_empty_tuple() {
  function _ffi_fn_enum_box_tup (line 296) | extern "C" fn _ffi_fn_enum_box_tup(buf_ptr: *const u8) -> _ffi_ret_ptr_u...
  function _ffi_fn_enum_opt_tup (line 306) | extern "C" fn _ffi_fn_enum_opt_tup(buf_ptr: *const u8) -> _ffi_ret_ptr_u...
  function _ffi_fn_enum_vec_tup (line 316) | extern "C" fn _ffi_fn_enum_vec_tup(buf_ptr: *const u8) -> _ffi_ret_ptr_u...
  function _ffi_fn_opt_box (line 326) | extern "C" fn _ffi_fn_opt_box(buf_ptr: *const u8, has_x_0: bool) -> _ffi...
  function _ffi_fn_opt_box_opt (line 341) | extern "C" fn _ffi_fn_opt_box_opt(buf_ptr: *const u8, has_x_0: bool) -> ...
  function _ffi_fn_opt_tup_0 (line 356) | extern "C" fn _ffi_fn_opt_tup_0(buf_ptr: *const u8, has_x_0: bool) -> _f...
  function _ffi_fn_opt_tup_1 (line 371) | extern "C" fn _ffi_fn_opt_tup_1(buf_ptr: *const u8, has_x_0: bool) -> _f...
  function _ffi_fn_opt_tup_2 (line 386) | extern "C" fn _ffi_fn_opt_tup_2(buf_ptr: *const u8, has_x_0: bool) -> _f...
  function _ffi_fn_rust_mem_leaked (line 402) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {
  function _ffi_fn_tup_box (line 407) | extern "C" fn _ffi_fn_tup_box(buf_ptr: *const u8) -> _ffi_ret_ptr_usize {
  function _ffi_fn_vec_box (line 422) | extern "C" fn _ffi_fn_vec_box(buf_ptr: *const u8, x_0_len: usize) -> _ff...
  function _ffi_fn_vec_box_vec (line 435) | extern "C" fn _ffi_fn_vec_box_vec(buf_ptr: *const u8, x_0_len: usize) ->...
  function _ffi_fn_vec_tup_0 (line 448) | extern "C" fn _ffi_fn_vec_tup_0(buf_ptr: *const u8, x_0_len: usize) -> _...
  function _ffi_fn_vec_tup_1 (line 461) | extern "C" fn _ffi_fn_vec_tup_1(buf_ptr: *const u8, x_0_len: usize) -> _...
  function _ffi_fn_vec_tup_2 (line 474) | extern "C" fn _ffi_fn_vec_tup_2(buf_ptr: *const u8, x_0_len: usize) -> _...
  type _ffi_ret_ptr_2_usize (line 487) | struct _ffi_ret_ptr_2_usize(*const u8, usize, usize);
  type _ffi_ret_ptr_usize (line 490) | struct _ffi_ret_ptr_usize(*const u8, usize);
  type _ffi_ret_ptr_usize_bool (line 493) | struct _ffi_ret_ptr_usize_bool(*const u8, usize, bool);
  function _ffi_vec__from_cpp (line 496) | fn _ffi_vec__from_cpp(len: usize, _: &mut *const u8) -> Vec<()> {
  function _ffi_vec__to_cpp (line 505) | fn _ffi_vec__to_cpp(items: Vec<()>, _: &mut Vec<u8>) {
  function _ffi_vec_box_i32_from_cpp (line 511) | fn _ffi_vec_box_i32_from_cpp(len: usize, end: &mut *const u8) -> Vec<Box...
  function _ffi_vec_box_i32_to_cpp (line 519) | fn _ffi_vec_box_i32_to_cpp(items: Vec<Box<i32>>, buf: &mut Vec<u8>) {
  function _ffi_vec_box_vec_i32_from_cpp (line 525) | fn _ffi_vec_box_vec_i32_from_cpp(len: usize, end: &mut *const u8) -> Vec...
  function _ffi_vec_box_vec_i32_to_cpp (line 533) | fn _ffi_vec_box_vec_i32_to_cpp(items: Vec<Box<Vec<i32>>>, buf: &mut Vec<...
  function _ffi_vec_i32_from_cpp (line 539) | fn _ffi_vec_i32_from_cpp(len: usize, end: &mut *const u8) -> Vec<(i32,)> {
  function _ffi_vec_i32_from_cpp2 (line 547) | fn _ffi_vec_i32_from_cpp2(len: usize, end: &mut *const u8) -> Vec<i32> {
  function _ffi_vec_i32_i32_from_cpp (line 555) | fn _ffi_vec_i32_i32_from_cpp(len: usize, end: &mut *const u8) -> Vec<(i3...
  function _ffi_vec_i32_i32_to_cpp (line 563) | fn _ffi_vec_i32_i32_to_cpp(items: Vec<(i32, i32)>, buf: &mut Vec<u8>) {
  function _ffi_vec_i32_to_cpp (line 570) | fn _ffi_vec_i32_to_cpp(items: Vec<(i32,)>, buf: &mut Vec<u8>) {
  function _ffi_vec_i32_to_cpp2 (line 576) | fn _ffi_vec_i32_to_cpp2(items: Vec<i32>, buf: &mut Vec<u8>) {

FILE: src/tests/snapshots/cpp_demo_derive_eq_2024/ffi.cpp
  type _ffi_ret_ptr_2_usize (line 7) | struct _ffi_ret_ptr_2_usize {
  type _ffi_ret_ptr_usize (line 13) | struct _ffi_ret_ptr_usize {
  type _ffi_ret_ptr_usize_bool (line 18) | struct _ffi_ret_ptr_usize_bool {
  function T (line 58) | T _ffi_read(const uint8_t* &ptr) {
  function _ffi_box_i32_i32_from_rust (line 65) | std::unique_ptr<std::tuple<int32_t, int32_t>> _ffi_box_i32_i32_from_rust...
  function _ffi_enum_EnumBoxTup_from_rust (line 72) | rust::EnumBoxTup _ffi_enum_EnumBoxTup_from_rust(const uint8_t*& end) {
  function _ffi_write (line 91) | void _ffi_write(T val, std::vector<uint8_t> &buf) {
  function _ffi_box_i32_i32_to_rust (line 95) | void _ffi_box_i32_i32_to_rust(std::tuple<int32_t, int32_t> val, std::vec...
  function _ffi_enum_EnumBoxTup_to_rust (line 100) | void _ffi_enum_EnumBoxTup_to_rust(rust::EnumBoxTup val, std::vector<uint...
  function _ffi_enum_EnumOptTup_from_rust (line 115) | rust::EnumOptTup _ffi_enum_EnumOptTup_from_rust(const uint8_t*& end) {
  function _ffi_enum_EnumOptTup_to_rust (line 138) | void _ffi_enum_EnumOptTup_to_rust(rust::EnumOptTup val, std::vector<uint...
  function _ffi_vec_i32_i32_from_rust (line 158) | std::vector<std::tuple<int32_t, int32_t>> _ffi_vec_i32_i32_from_rust(uin...
  function _ffi_enum_EnumVecTup_from_rust (line 170) | rust::EnumVecTup _ffi_enum_EnumVecTup_from_rust(const uint8_t*& end) {
  function _ffi_vec_i32_i32_to_rust (line 189) | void _ffi_vec_i32_i32_to_rust(std::vector<std::tuple<int32_t, int32_t>>&...
  function _ffi_enum_EnumVecTup_to_rust (line 196) | void _ffi_enum_EnumVecTup_to_rust(rust::EnumVecTup val, std::vector<uint...
  function _ffi_box_option_i32_from_rust (line 213) | std::unique_ptr<std::optional<int32_t>> _ffi_box_option_i32_from_rust(co...
  function _ffi_box_option_i32_to_rust (line 218) | void _ffi_box_option_i32_to_rust(std::optional<int32_t> val, std::vector...
  function _ffi_box_i32_from_rust2 (line 230) | std::unique_ptr<int32_t> _ffi_box_i32_from_rust2(const uint8_t*& end) {
  function _ffi_box_option_box_i32_from_rust (line 235) | std::unique_ptr<std::optional<std::unique_ptr<int32_t>>> _ffi_box_option...
  function _ffi_box_i32_to_rust2 (line 240) | void _ffi_box_i32_to_rust2(int32_t val, std::vector<uint8_t>& buf) {
  function _ffi_box_option_box_i32_to_rust (line 244) | void _ffi_box_option_box_i32_to_rust(std::optional<std::unique_ptr<int32...
  function _ffi_box__from_rust (line 252) | std::unique_ptr<std::tuple<>> _ffi_box__from_rust(const uint8_t*& end) {
  function _ffi_box__to_rust (line 257) | void _ffi_box__to_rust(std::tuple<> val, std::vector<uint8_t>& buf) {
  function _ffi_box_i32_from_rust (line 261) | std::unique_ptr<std::tuple<int32_t>> _ffi_box_i32_from_rust(const uint8_...
  function _ffi_box_i32_to_rust (line 267) | void _ffi_box_i32_to_rust(std::tuple<int32_t> val, std::vector<uint8_t>&...
  function _ffi_vec_i32_from_rust2 (line 271) | std::vector<int32_t> _ffi_vec_i32_from_rust2(uintptr_t len, const uint8_...
  function _ffi_box_vec_i32_from_rust (line 281) | std::unique_ptr<std::vector<int32_t>> _ffi_box_vec_i32_from_rust(const u...
  function _ffi_vec_i32_to_rust2 (line 287) | void _ffi_vec_i32_to_rust2(std::vector<int32_t>&& items, std::vector<uin...
  function _ffi_box_vec_i32_to_rust (line 293) | void _ffi_box_vec_i32_to_rust(std::vector<int32_t> val, std::vector<uint...
  function _ffi_vec_box_i32_from_rust (line 299) | std::vector<std::unique_ptr<int32_t>> _ffi_vec_box_i32_from_rust(uintptr...
  function _ffi_box_vec_box_i32_from_rust (line 309) | std::unique_ptr<std::vector<std::unique_ptr<int32_t>>> _ffi_box_vec_box_...
  function _ffi_vec_box_i32_to_rust (line 315) | void _ffi_vec_box_i32_to_rust(std::vector<std::unique_ptr<int32_t>>&& it...
  function _ffi_box_vec_box_i32_to_rust (line 321) | void _ffi_box_vec_box_i32_to_rust(std::vector<std::unique_ptr<int32_t>> ...
  function _ffi_box_bool_from_rust (line 327) | std::unique_ptr<bool> _ffi_box_bool_from_rust(const uint8_t*& end) {
  function _ffi_box_bool_to_rust (line 332) | void _ffi_box_bool_to_rust(bool val, std::vector<uint8_t>& buf) {
  function _ffi_vec_box_vec_i32_from_rust (line 336) | std::vector<std::unique_ptr<std::vector<int32_t>>> _ffi_vec_box_vec_i32_...
  function _ffi_vec_box_vec_i32_to_rust (line 346) | void _ffi_vec_box_vec_i32_to_rust(std::vector<std::unique_ptr<std::vecto...
  function _ffi_vec__from_rust (line 352) | std::vector<std::tuple<>> _ffi_vec__from_rust(uintptr_t len, const uint8...
  function _ffi_vec__to_rust (line 362) | void _ffi_vec__to_rust(std::vector<std::tuple<>>&& items, std::vector<ui...
  function _ffi_vec_i32_from_rust (line 368) | std::vector<std::tuple<int32_t>> _ffi_vec_i32_from_rust(uintptr_t len, c...
  function _ffi_vec_i32_to_rust (line 379) | void _ffi_vec_i32_to_rust(std::vector<std::tuple<int32_t>>&& items, std:...

FILE: src/tests/snapshots/cpp_demo_derive_eq_2024/ffi.h
  function namespace (line 12) | namespace rust {
  function namespace (line 61) | namespace detail {
  type EnumBoxTup__Baz (line 74) | struct EnumBoxTup__Baz {
  type EnumBoxTup (line 83) | struct EnumBoxTup
  function namespace (line 93) | namespace detail {
  type EnumOptTup__Baz (line 106) | struct EnumOptTup__Baz {
  type EnumOptTup (line 115) | struct EnumOptTup
  function namespace (line 125) | namespace detail {
  type EnumVecTup__Baz (line 138) | struct EnumVecTup__Baz {
  type EnumVecTup (line 147) | struct EnumVecTup
  type OptBox (line 157) | struct OptBox {
  type OptBoxOpt (line 163) | struct OptBoxOpt {
  type OptTup0 (line 169) | struct OptTup0 {
  type OptTup1 (line 175) | struct OptTup1 {
  type OptTup2 (line 181) | struct OptTup2 {
  type TupBox (line 187) | struct TupBox {
  type VecBox (line 193) | struct VecBox {
  type VecBoxVec (line 199) | struct VecBoxVec {
  type VecTup0 (line 205) | struct VecTup0 {
  type VecTup1 (line 211) | struct VecTup1 {
  type VecTup2 (line 217) | struct VecTup2 {

FILE: src/tests/snapshots/cpp_demo_derive_eq_2024/miniffi.rs
  function _ffi_box__from_cpp (line 4) | fn _ffi_box__from_cpp(_: &mut *const u8) -> Box<()> {
  function _ffi_box__to_cpp (line 9) | fn _ffi_box__to_cpp(val: (), _: &mut Vec<u8>) {
  function _ffi_box_bool_from_cpp (line 13) | fn _ffi_box_bool_from_cpp(end: &mut *const u8) -> Box<bool> {
  function _ffi_box_bool_to_cpp (line 17) | fn _ffi_box_bool_to_cpp(val: bool, buf: &mut Vec<u8>) {
  function _ffi_box_i32_from_cpp (line 21) | fn _ffi_box_i32_from_cpp(end: &mut *const u8) -> Box<(i32,)> {
  function _ffi_box_i32_from_cpp2 (line 25) | fn _ffi_box_i32_from_cpp2(end: &mut *const u8) -> Box<i32> {
  function _ffi_box_i32_i32_from_cpp (line 29) | fn _ffi_box_i32_i32_from_cpp(end: &mut *const u8) -> Box<(i32, i32)> {
  function _ffi_box_i32_i32_to_cpp (line 33) | fn _ffi_box_i32_i32_to_cpp(val: (i32, i32), buf: &mut Vec<u8>) {
  function _ffi_box_i32_to_cpp (line 38) | fn _ffi_box_i32_to_cpp(val: (i32,), buf: &mut Vec<u8>) {
  function _ffi_box_i32_to_cpp2 (line 42) | fn _ffi_box_i32_to_cpp2(val: i32, buf: &mut Vec<u8>) {
  function _ffi_box_option_box_i32_from_cpp (line 46) | fn _ffi_box_option_box_i32_from_cpp(end: &mut *const u8) -> Box<Option<B...
  function _ffi_box_option_box_i32_to_cpp (line 50) | fn _ffi_box_option_box_i32_to_cpp(val: Option<Box<i32>>, buf: &mut Vec<u...
  function _ffi_box_option_i32_from_cpp (line 57) | fn _ffi_box_option_i32_from_cpp(end: &mut *const u8) -> Box<Option<i32>> {
  function _ffi_box_option_i32_to_cpp (line 61) | fn _ffi_box_option_i32_to_cpp(val: Option<i32>, buf: &mut Vec<u8>) {
  function _ffi_box_vec_box_i32_from_cpp (line 68) | fn _ffi_box_vec_box_i32_from_cpp(end: &mut *const u8) -> Box<Vec<Box<i32...
  function _ffi_box_vec_box_i32_to_cpp (line 72) | fn _ffi_box_vec_box_i32_to_cpp(val: Vec<Box<i32>>, buf: &mut Vec<u8>) {
  function _ffi_box_vec_i32_from_cpp (line 77) | fn _ffi_box_vec_i32_from_cpp(end: &mut *const u8) -> Box<Vec<i32>> {
  function _ffi_box_vec_i32_to_cpp (line 81) | fn _ffi_box_vec_i32_to_cpp(val: Vec<i32>, buf: &mut Vec<u8>) {
  function _ffi_alloc (line 87) | extern "C" fn _ffi_alloc(len: usize) -> *const u8 {
  function _ffi_buf_from_host (line 91) | fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) {
  function _ffi_dealloc (line 97) | extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) {
  function _ffi_buf_to_host (line 101) | fn _ffi_buf_to_host(buf: Vec<u8>) -> (*const u8, usize) {
  function _ffi_read (line 106) | fn _ffi_read<T: Copy>(ptr: &mut *const u8) -> T {
  function _ffi_enum_EnumBoxTup_from_cpp (line 113) | fn _ffi_enum_EnumBoxTup_from_cpp(end: &mut *const u8) -> EnumBoxTup {
  function _ffi_write (line 122) | fn _ffi_write<T: Copy>(val: T, buf: &mut Vec<u8>) {
  function _ffi_enum_EnumBoxTup_to_cpp (line 129) | fn _ffi_enum_EnumBoxTup_to_cpp(val: EnumBoxTup, buf: &mut Vec<u8>) {
  function _ffi_enum_EnumOptTup_from_cpp (line 145) | fn _ffi_enum_EnumOptTup_from_cpp(end: &mut *const u8) -> EnumOptTup {
  function _ffi_enum_EnumOptTup_to_cpp (line 155) | fn _ffi_enum_EnumOptTup_to_cpp(val: EnumOptTup, buf: &mut Vec<u8>) {
  function _ffi_enum_EnumVecTup_from_cpp (line 175) | fn _ffi_enum_EnumVecTup_from_cpp(end: &mut *const u8) -> EnumVecTup {
  function _ffi_enum_EnumVecTup_to_cpp (line 185) | fn _ffi_enum_EnumVecTup_to_cpp(val: EnumVecTup, buf: &mut Vec<u8>) {
  function _ffi_fn_box_opt (line 202) | extern "C" fn _ffi_fn_box_opt(buf_ptr: *const u8) -> _ffi_ret_ptr_usize {
  function _ffi_fn_box_opt_box (line 214) | extern "C" fn _ffi_fn_box_opt_box(buf_ptr: *const u8) -> _ffi_ret_ptr_us...
  function _ffi_fn_box_tup_0 (line 226) | extern "C" fn _ffi_fn_box_tup_0(buf_ptr: *const u8) -> _ffi_ret_ptr_usize {
  function _ffi_fn_box_tup_1 (line 238) | extern "C" fn _ffi_fn_box_tup_1(buf_ptr: *const u8) -> _ffi_ret_ptr_usize {
  function _ffi_fn_box_tup_2 (line 250) | extern "C" fn _ffi_fn_box_tup_2(buf_ptr: *const u8) -> _ffi_ret_ptr_usize {
  function _ffi_fn_box_vec (line 262) | extern "C" fn _ffi_fn_box_vec(buf_ptr: *const u8) -> _ffi_ret_ptr_usize {
  function _ffi_fn_box_vec_box (line 274) | extern "C" fn _ffi_fn_box_vec_box(buf_ptr: *const u8) -> _ffi_ret_ptr_us...
  function _ffi_fn_empty_struct (line 286) | extern "C" fn _ffi_fn_empty_struct() {
  function _ffi_fn_empty_tuple (line 291) | extern "C" fn _ffi_fn_empty_tuple() {
  function _ffi_fn_enum_box_tup (line 296) | extern "C" fn _ffi_fn_enum_box_tup(buf_ptr: *const u8) -> _ffi_ret_ptr_u...
  function _ffi_fn_enum_opt_tup (line 306) | extern "C" fn _ffi_fn_enum_opt_tup(buf_ptr: *const u8) -> _ffi_ret_ptr_u...
  function _ffi_fn_enum_vec_tup (line 316) | extern "C" fn _ffi_fn_enum_vec_tup(buf_ptr: *const u8) -> _ffi_ret_ptr_u...
  function _ffi_fn_opt_box (line 326) | extern "C" fn _ffi_fn_opt_box(buf_ptr: *const u8, has_x_0: bool) -> _ffi...
  function _ffi_fn_opt_box_opt (line 341) | extern "C" fn _ffi_fn_opt_box_opt(buf_ptr: *const u8, has_x_0: bool) -> ...
  function _ffi_fn_opt_tup_0 (line 356) | extern "C" fn _ffi_fn_opt_tup_0(buf_ptr: *const u8, has_x_0: bool) -> _f...
  function _ffi_fn_opt_tup_1 (line 371) | extern "C" fn _ffi_fn_opt_tup_1(buf_ptr: *const u8, has_x_0: bool) -> _f...
  function _ffi_fn_opt_tup_2 (line 386) | extern "C" fn _ffi_fn_opt_tup_2(buf_ptr: *const u8, has_x_0: bool) -> _f...
  function _ffi_fn_rust_mem_leaked (line 402) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {
  function _ffi_fn_tup_box (line 407) | extern "C" fn _ffi_fn_tup_box(buf_ptr: *const u8) -> _ffi_ret_ptr_usize {
  function _ffi_fn_vec_box (line 422) | extern "C" fn _ffi_fn_vec_box(buf_ptr: *const u8, x_0_len: usize) -> _ff...
  function _ffi_fn_vec_box_vec (line 435) | extern "C" fn _ffi_fn_vec_box_vec(buf_ptr: *const u8, x_0_len: usize) ->...
  function _ffi_fn_vec_tup_0 (line 448) | extern "C" fn _ffi_fn_vec_tup_0(buf_ptr: *const u8, x_0_len: usize) -> _...
  function _ffi_fn_vec_tup_1 (line 461) | extern "C" fn _ffi_fn_vec_tup_1(buf_ptr: *const u8, x_0_len: usize) -> _...
  function _ffi_fn_vec_tup_2 (line 474) | extern "C" fn _ffi_fn_vec_tup_2(buf_ptr: *const u8, x_0_len: usize) -> _...
  type _ffi_ret_ptr_2_usize (line 487) | struct _ffi_ret_ptr_2_usize(*const u8, usize, usize);
  type _ffi_ret_ptr_usize (line 490) | struct _ffi_ret_ptr_usize(*const u8, usize);
  type _ffi_ret_ptr_usize_bool (line 493) | struct _ffi_ret_ptr_usize_bool(*const u8, usize, bool);
  function _ffi_vec__from_cpp (line 496) | fn _ffi_vec__from_cpp(len: usize, _: &mut *const u8) -> Vec<()> {
  function _ffi_vec__to_cpp (line 505) | fn _ffi_vec__to_cpp(items: Vec<()>, _: &mut Vec<u8>) {
  function _ffi_vec_box_i32_from_cpp (line 511) | fn _ffi_vec_box_i32_from_cpp(len: usize, end: &mut *const u8) -> Vec<Box...
  function _ffi_vec_box_i32_to_cpp (line 519) | fn _ffi_vec_box_i32_to_cpp(items: Vec<Box<i32>>, buf: &mut Vec<u8>) {
  function _ffi_vec_box_vec_i32_from_cpp (line 525) | fn _ffi_vec_box_vec_i32_from_cpp(len: usize, end: &mut *const u8) -> Vec...
  function _ffi_vec_box_vec_i32_to_cpp (line 533) | fn _ffi_vec_box_vec_i32_to_cpp(items: Vec<Box<Vec<i32>>>, buf: &mut Vec<...
  function _ffi_vec_i32_from_cpp (line 539) | fn _ffi_vec_i32_from_cpp(len: usize, end: &mut *const u8) -> Vec<(i32,)> {
  function _ffi_vec_i32_from_cpp2 (line 547) | fn _ffi_vec_i32_from_cpp2(len: usize, end: &mut *const u8) -> Vec<i32> {
  function _ffi_vec_i32_i32_from_cpp (line 555) | fn _ffi_vec_i32_i32_from_cpp(len: usize, end: &mut *const u8) -> Vec<(i3...
  function _ffi_vec_i32_i32_to_cpp (line 563) | fn _ffi_vec_i32_i32_to_cpp(items: Vec<(i32, i32)>, buf: &mut Vec<u8>) {
  function _ffi_vec_i32_to_cpp (line 570) | fn _ffi_vec_i32_to_cpp(items: Vec<(i32,)>, buf: &mut Vec<u8>) {
  function _ffi_vec_i32_to_cpp2 (line 576) | fn _ffi_vec_i32_to_cpp2(items: Vec<i32>, buf: &mut Vec<u8>) {

FILE: src/tests/snapshots/cpp_demo_enum_2021/ffi.h
  function namespace (line 12) | namespace rust {
  function namespace (line 41) | namespace detail {
  type InnerEnum (line 49) | struct InnerEnum
  function namespace (line 57) | namespace detail {
  type NestedStruct (line 68) | struct NestedStruct
  type InnerStruct (line 77) | struct InnerStruct {
  function namespace (line 81) | namespace detail {
  type NestedBox (line 92) | struct NestedBox
  function namespace (line 101) | namespace detail {
  type NestedOption (line 112) | struct NestedOption
  function namespace (line 121) | namespace detail {
  type NestedTuple (line 132) | struct NestedTuple
  function namespace (line 141) | namespace detail {
  type NestedVec (line 152) | struct NestedVec

FILE: src/tests/snapshots/cpp_demo_enum_2021/miniffi.rs
  function _ffi_fn_rust_mem_leaked (line 4) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {

FILE: src/tests/snapshots/cpp_demo_enum_2024/ffi.h
  function namespace (line 12) | namespace rust {
  function namespace (line 41) | namespace detail {
  type InnerEnum (line 49) | struct InnerEnum
  function namespace (line 57) | namespace detail {
  type NestedStruct (line 68) | struct NestedStruct
  type InnerStruct (line 77) | struct InnerStruct {
  function namespace (line 81) | namespace detail {
  type NestedBox (line 92) | struct NestedBox
  function namespace (line 101) | namespace detail {
  type NestedOption (line 112) | struct NestedOption
  function namespace (line 121) | namespace detail {
  type NestedTuple (line 132) | struct NestedTuple
  function namespace (line 141) | namespace detail {
  type NestedVec (line 152) | struct NestedVec

FILE: src/tests/snapshots/cpp_demo_enum_2024/miniffi.rs
  function _ffi_fn_rust_mem_leaked (line 4) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {

FILE: src/tests/snapshots/cpp_demo_keyword_2021/ffi.h
  function namespace (line 7) | namespace rust {

FILE: src/tests/snapshots/cpp_demo_keyword_2021/miniffi.rs
  function _ffi_fn_rust_mem_leaked (line 4) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {
  function _ffi_fn_test_alignas (line 9) | extern "C" fn _ffi_fn_test_alignas(alignas2: i32) -> i32 {
  function _ffi_fn_test_alignof (line 14) | extern "C" fn _ffi_fn_test_alignof(alignof2: i32) -> i32 {
  function _ffi_fn_test_and (line 19) | extern "C" fn _ffi_fn_test_and(and2: i32) -> i32 {
  function _ffi_fn_test_and_eq (line 24) | extern "C" fn _ffi_fn_test_and_eq(and_eq2: i32) -> i32 {
  function _ffi_fn_test_asm (line 29) | extern "C" fn _ffi_fn_test_asm(asm2: i32) -> i32 {
  function _ffi_fn_test_associatedtype (line 34) | extern "C" fn _ffi_fn_test_associatedtype(associatedtype: i32) -> i32 {
  function _ffi_fn_test_associativity (line 39) | extern "C" fn _ffi_fn_test_associativity(associativity: i32) -> i32 {
  function _ffi_fn_test_atomic_cancel (line 44) | extern "C" fn _ffi_fn_test_atomic_cancel(atomic_cancel2: i32) -> i32 {
  function _ffi_fn_test_atomic_commit (line 49) | extern "C" fn _ffi_fn_test_atomic_commit(atomic_commit2: i32) -> i32 {
  function _ffi_fn_test_atomic_noexcept (line 54) | extern "C" fn _ffi_fn_test_atomic_noexcept(atomic_noexcept2: i32) -> i32 {
  function _ffi_fn_test_auto (line 59) | extern "C" fn _ffi_fn_test_auto(auto2: i32) -> i32 {
  function _ffi_fn_test_bitand (line 64) | extern "C" fn _ffi_fn_test_bitand(bitand2: i32) -> i32 {
  function _ffi_fn_test_bitor (line 69) | extern "C" fn _ffi_fn_test_bitor(bitor2: i32) -> i32 {
  function _ffi_fn_test_bool (line 74) | extern "C" fn _ffi_fn_test_bool(bool2: i32) -> i32 {
  function _ffi_fn_test_boolean (line 79) | extern "C" fn _ffi_fn_test_boolean(boolean: i32) -> i32 {
  function _ffi_fn_test_borrowing (line 84) | extern "C" fn _ffi_fn_test_borrowing(borrowing: i32) -> i32 {
  function _ffi_fn_test_byte (line 89) | extern "C" fn _ffi_fn_test_byte(byte: i32) -> i32 {
  function _ffi_fn_test_case (line 94) | extern "C" fn _ffi_fn_test_case(case2: i32) -> i32 {
  function _ffi_fn_test_catch (line 99) | extern "C" fn _ffi_fn_test_catch(catch2: i32) -> i32 {
  function _ffi_fn_test_char (line 104) | extern "C" fn _ffi_fn_test_char(char2: i32) -> i32 {
  function _ffi_fn_test_char16_t (line 109) | extern "C" fn _ffi_fn_test_char16_t(char16_t2: i32) -> i32 {
  function _ffi_fn_test_char32_t (line 114) | extern "C" fn _ffi_fn_test_char32_t(char32_t2: i32) -> i32 {
  function _ffi_fn_test_char8_t (line 119) | extern "C" fn _ffi_fn_test_char8_t(char8_t2: i32) -> i32 {
  function _ffi_fn_test_class (line 124) | extern "C" fn _ffi_fn_test_class(class2: i32) -> i32 {
  function _ffi_fn_test_co_await (line 129) | extern "C" fn _ffi_fn_test_co_await(co_await2: i32) -> i32 {
  function _ffi_fn_test_co_return (line 134) | extern "C" fn _ffi_fn_test_co_return(co_return2: i32) -> i32 {
  function _ffi_fn_test_co_yield (line 139) | extern "C" fn _ffi_fn_test_co_yield(co_yield2: i32) -> i32 {
  function _ffi_fn_test_compl (line 144) | extern "C" fn _ffi_fn_test_compl(compl2: i32) -> i32 {
  function _ffi_fn_test_concept (line 149) | extern "C" fn _ffi_fn_test_concept(concept2: i32) -> i32 {
  function _ffi_fn_test_const_cast (line 154) | extern "C" fn _ffi_fn_test_const_cast(const_cast2: i32) -> i32 {
  function _ffi_fn_test_consteval (line 159) | extern "C" fn _ffi_fn_test_consteval(consteval2: i32) -> i32 {
  function _ffi_fn_test_constexpr (line 164) | extern "C" fn _ffi_fn_test_constexpr(constexpr2: i32) -> i32 {
  function _ffi_fn_test_constinit (line 169) | extern "C" fn _ffi_fn_test_constinit(constinit2: i32) -> i32 {
  function _ffi_fn_test_consuming (line 174) | extern "C" fn _ffi_fn_test_consuming(consuming: i32) -> i32 {
  function _ffi_fn_test_contract_assert (line 179) | extern "C" fn _ffi_fn_test_contract_assert(contract_assert2: i32) -> i32 {
  function _ffi_fn_test_convenience (line 184) | extern "C" fn _ffi_fn_test_convenience(convenience: i32) -> i32 {
  function _ffi_fn_test_debugger (line 189) | extern "C" fn _ffi_fn_test_debugger(debugger: i32) -> i32 {
  function _ffi_fn_test_decltype (line 194) | extern "C" fn _ffi_fn_test_decltype(decltype2: i32) -> i32 {
  function _ffi_fn_test_default (line 199) | extern "C" fn _ffi_fn_test_default(default2: i32) -> i32 {
  function _ffi_fn_test_defer (line 204) | extern "C" fn _ffi_fn_test_defer(defer: i32) -> i32 {
  function _ffi_fn_test_deinit (line 209) | extern "C" fn _ffi_fn_test_deinit(deinit: i32) -> i32 {
  function _ffi_fn_test_delete (line 214) | extern "C" fn _ffi_fn_test_delete(delete2: i32) -> i32 {
  function _ffi_fn_test_double (line 219) | extern "C" fn _ffi_fn_test_double(double2: i32) -> i32 {
  function _ffi_fn_test_dynamic (line 224) | extern "C" fn _ffi_fn_test_dynamic(dynamic: i32) -> i32 {
  function _ffi_fn_test_dynamic_cast (line 229) | extern "C" fn _ffi_fn_test_dynamic_cast(dynamic_cast2: i32) -> i32 {
  function _ffi_fn_test_explicit (line 234) | extern "C" fn _ffi_fn_test_explicit(explicit2: i32) -> i32 {
  function _ffi_fn_test_export (line 239) | extern "C" fn _ffi_fn_test_export(export2: i32) -> i32 {
  function _ffi_fn_test_extends (line 244) | extern "C" fn _ffi_fn_test_extends(extends: i32) -> i32 {
  function _ffi_fn_test_extension (line 249) | extern "C" fn _ffi_fn_test_extension(extension: i32) -> i32 {
  function _ffi_fn_test_fallthrough (line 254) | extern "C" fn _ffi_fn_test_fallthrough(fallthrough: i32) -> i32 {
  function _ffi_fn_test_fileprivate (line 259) | extern "C" fn _ffi_fn_test_fileprivate(fileprivate: i32) -> i32 {
  function _ffi_fn_test_finally (line 264) | extern "C" fn _ffi_fn_test_finally(finally: i32) -> i32 {
  function _ffi_fn_test_float (line 269) | extern "C" fn _ffi_fn_test_float(float2: i32) -> i32 {
  function _ffi_fn_test_friend (line 274) | extern "C" fn _ffi_fn_test_friend(friend2: i32) -> i32 {
  function _ffi_fn_test_func (line 279) | extern "C" fn _ffi_fn_test_func(func: i32) -> i32 {
  function _ffi_fn_test_function (line 284) | extern "C" fn _ffi_fn_test_function(function: i32) -> i32 {
  function _ffi_fn_test_get (line 289) | extern "C" fn _ffi_fn_test_get(get: i32) -> i32 {
  function _ffi_fn_test_goto (line 294) | extern "C" fn _ffi_fn_test_goto(goto2: i32) -> i32 {
  function _ffi_fn_test_guard (line 299) | extern "C" fn _ffi_fn_test_guard(guard: i32) -> i32 {
  function _ffi_fn_test_implements (line 304) | extern "C" fn _ffi_fn_test_implements(implements: i32) -> i32 {
  function _ffi_fn_test_import (line 309) | extern "C" fn _ffi_fn_test_import(import: i32) -> i32 {
  function _ffi_fn_test_indirect (line 314) | extern "C" fn _ffi_fn_test_indirect(indirect: i32) -> i32 {
  function _ffi_fn_test_infix (line 319) | extern "C" fn _ffi_fn_test_infix(infix: i32) -> i32 {
  function _ffi_fn_test_init (line 324) | extern "C" fn _ffi_fn_test_init(init: i32) -> i32 {
  function _ffi_fn_test_inline (line 329) | extern "C" fn _ffi_fn_test_inline(inline2: i32) -> i32 {
  function _ffi_fn_test_inout (line 334) | extern "C" fn _ffi_fn_test_inout(inout: i32) -> i32 {
  function _ffi_fn_test_instanceof (line 339) | extern "C" fn _ffi_fn_test_instanceof(instanceof: i32) -> i32 {
  function _ffi_fn_test_int (line 344) | extern "C" fn _ffi_fn_test_int(int2: i32) -> i32 {
  function _ffi_fn_test_interface (line 349) | extern "C" fn _ffi_fn_test_interface(interface: i32) -> i32 {
  function _ffi_fn_test_internal (line 354) | extern "C" fn _ffi_fn_test_internal(internal: i32) -> i32 {
  function _ffi_fn_test_is (line 359) | extern "C" fn _ffi_fn_test_is(is: i32) -> i32 {
  function _ffi_fn_test_lazy (line 364) | extern "C" fn _ffi_fn_test_lazy(lazy: i32) -> i32 {
  function _ffi_fn_test_left (line 369) | extern "C" fn _ffi_fn_test_left(left: i32) -> i32 {
  function _ffi_fn_test_long (line 374) | extern "C" fn _ffi_fn_test_long(long2: i32) -> i32 {
  function _ffi_fn_test_mutable (line 379) | extern "C" fn _ffi_fn_test_mutable(mutable2: i32) -> i32 {
  function _ffi_fn_test_mutating (line 384) | extern "C" fn _ffi_fn_test_mutating(mutating: i32) -> i32 {
  function _ffi_fn_test_namespace (line 389) | extern "C" fn _ffi_fn_test_namespace(namespace2: i32) -> i32 {
  function _ffi_fn_test_native (line 394) | extern "C" fn _ffi_fn_test_native(native: i32) -> i32 {
  function _ffi_fn_test_new (line 399) | extern "C" fn _ffi_fn_test_new(new2: i32) -> i32 {
  function _ffi_fn_test_nil (line 404) | extern "C" fn _ffi_fn_test_nil(nil: i32) -> i32 {
  function _ffi_fn_test_noexcept (line 409) | extern "C" fn _ffi_fn_test_noexcept(noexcept2: i32) -> i32 {
  function _ffi_fn_test_none (line 414) | extern "C" fn _ffi_fn_test_none(none: i32) -> i32 {
  function _ffi_fn_test_nonisolated (line 419) | extern "C" fn _ffi_fn_test_nonisolated(nonisolated: i32) -> i32 {
  function _ffi_fn_test_nonmutating (line 424) | extern "C" fn _ffi_fn_test_nonmutating(nonmutating: i32) -> i32 {
  function _ffi_fn_test_not (line 429) | extern "C" fn _ffi_fn_test_not(not2: i32) -> i32 {
  function _ffi_fn_test_not_eq (line 434) | extern "C" fn _ffi_fn_test_not_eq(not_eq2: i32) -> i32 {
  function _ffi_fn_test_null (line 439) | extern "C" fn _ffi_fn_test_null(null: i32) -> i32 {
  function _ffi_fn_test_nullptr (line 444) | extern "C" fn _ffi_fn_test_nullptr(nullptr2: i32) -> i32 {
  function _ffi_fn_test_open (line 449) | extern "C" fn _ffi_fn_test_open(open: i32) -> i32 {
  function _ffi_fn_test_operator (line 454) | extern "C" fn _ffi_fn_test_operator(operator2: i32) -> i32 {
  function _ffi_fn_test_optional (line 459) | extern "C" fn _ffi_fn_test_optional(optional: i32) -> i32 {
  function _ffi_fn_test_or (line 464) | extern "C" fn _ffi_fn_test_or(or2: i32) -> i32 {
  function _ffi_fn_test_or_eq (line 469) | extern "C" fn _ffi_fn_test_or_eq(or_eq2: i32) -> i32 {
  function _ffi_fn_test_package (line 474) | extern "C" fn _ffi_fn_test_package(package: i32) -> i32 {
  function _ffi_fn_test_postfix (line 479) | extern "C" fn _ffi_fn_test_postfix(postfix: i32) -> i32 {
  function _ffi_fn_test_precedence (line 484) | extern "C" fn _ffi_fn_test_precedence(precedence: i32) -> i32 {
  function _ffi_fn_test_precedencegroup (line 489) | extern "C" fn _ffi_fn_test_precedencegroup(precedencegroup: i32) -> i32 {
  function _ffi_fn_test_prefix (line 494) | extern "C" fn _ffi_fn_test_prefix(prefix: i32) -> i32 {
  function _ffi_fn_test_private (line 499) | extern "C" fn _ffi_fn_test_private(private2: i32) -> i32 {
  function _ffi_fn_test_protected (line 504) | extern "C" fn _ffi_fn_test_protected(protected2: i32) -> i32 {
  function _ffi_fn_test_protocol (line 509) | extern "C" fn _ffi_fn_test_protocol(protocol: i32) -> i32 {
  function _ffi_fn_test_public (line 514) | extern "C" fn _ffi_fn_test_public(public2: i32) -> i32 {
  function _ffi_fn_test_reflexpr (line 519) | extern "C" fn _ffi_fn_test_reflexpr(reflexpr2: i32) -> i32 {
  function _ffi_fn_test_register (line 524) | extern "C" fn _ffi_fn_test_register(register2: i32) -> i32 {
  function _ffi_fn_test_reinterpret_cast (line 529) | extern "C" fn _ffi_fn_test_reinterpret_cast(reinterpret_cast2: i32) -> i...
  function _ffi_fn_test_repeat (line 534) | extern "C" fn _ffi_fn_test_repeat(repeat: i32) -> i32 {
  function _ffi_fn_test_required (line 539) | extern "C" fn _ffi_fn_test_required(required: i32) -> i32 {
  function _ffi_fn_test_requires (line 544) | extern "C" fn _ffi_fn_test_requires(requires2: i32) -> i32 {
  function _ffi_fn_test_rethrows (line 549) | extern "C" fn _ffi_fn_test_rethrows(rethrows: i32) -> i32 {
  function _ffi_fn_test_right (line 554) | extern "C" fn _ffi_fn_test_right(right: i32) -> i32 {
  function _ffi_fn_test_set (line 559) | extern "C" fn _ffi_fn_test_set(set: i32) -> i32 {
  function _ffi_fn_test_short (line 564) | extern "C" fn _ffi_fn_test_short(short2: i32) -> i32 {
  function _ffi_fn_test_signed (line 569) | extern "C" fn _ffi_fn_test_signed(signed2: i32) -> i32 {
  function _ffi_fn_test_sizeof (line 574) | extern "C" fn _ffi_fn_test_sizeof(sizeof2: i32) -> i32 {
  function _ffi_fn_test_some (line 579) | extern "C" fn _ffi_fn_test_some(some: i32) -> i32 {
  function _ffi_fn_test_static_assert (line 584) | extern "C" fn _ffi_fn_test_static_assert(static_assert2: i32) -> i32 {
  function _ffi_fn_test_static_cast (line 589) | extern "C" fn _ffi_fn_test_static_cast(static_cast2: i32) -> i32 {
  function _ffi_fn_test_subscript (line 594) | extern "C" fn _ffi_fn_test_subscript(subscript: i32) -> i32 {
  function _ffi_fn_test_switch (line 599) | extern "C" fn _ffi_fn_test_switch(switch2: i32) -> i32 {
  function _ffi_fn_test_synchronized (line 604) | extern "C" fn _ffi_fn_test_synchronized(synchronized2: i32) -> i32 {
  function _ffi_fn_test_template (line 609) | extern "C" fn _ffi_fn_test_template(template2: i32) -> i32 {
  function _ffi_fn_test_this (line 614) | extern "C" fn _ffi_fn_test_this(this2: i32) -> i32 {
  function _ffi_fn_test_thread_local (line 619) | extern "C" fn _ffi_fn_test_thread_local(thread_local2: i32) -> i32 {
  function _ffi_fn_test_throw (line 624) | extern "C" fn _ffi_fn_test_throw(throw2: i32) -> i32 {
  function _ffi_fn_test_throws (line 629) | extern "C" fn _ffi_fn_test_throws(throws: i32) -> i32 {
  function _ffi_fn_test_transient (line 634) | extern "C" fn _ffi_fn_test_transient(transient: i32) -> i32 {
  function _ffi_fn_test_typealias (line 639) | extern "C" fn _ffi_fn_test_typealias(typealias: i32) -> i32 {
  function _ffi_fn_test_typedef (line 644) | extern "C" fn _ffi_fn_test_typedef(typedef2: i32) -> i32 {
  function _ffi_fn_test_typeid (line 649) | extern "C" fn _ffi_fn_test_typeid(typeid2: i32) -> i32 {
  function _ffi_fn_test_typename (line 654) | extern "C" fn _ffi_fn_test_typename(typename2: i32) -> i32 {
  function _ffi_fn_test_undefined (line 659) | extern "C" fn _ffi_fn_test_undefined(undefined: i32) -> i32 {
  function _ffi_fn_test_union (line 664) | extern "C" fn _ffi_fn_test_union(union2: i32) -> i32 {
  function _ffi_fn_test_unowned (line 669) | extern "C" fn _ffi_fn_test_unowned(unowned: i32) -> i32 {
  function _ffi_fn_test_unsigned (line 674) | extern "C" fn _ffi_fn_test_unsigned(unsigned2: i32) -> i32 {
  function _ffi_fn_test_using (line 679) | extern "C" fn _ffi_fn_test_using(using2: i32) -> i32 {
  function _ffi_fn_test_var (line 684) | extern "C" fn _ffi_fn_test_var(var: i32) -> i32 {
  function _ffi_fn_test_void (line 689) | extern "C" fn _ffi_fn_test_void(void2: i32) -> i32 {
  function _ffi_fn_test_volatile (line 694) | extern "C" fn _ffi_fn_test_volatile(volatile2: i32) -> i32 {
  function _ffi_fn_test_wchar_t (line 699) | extern "C" fn _ffi_fn_test_wchar_t(wchar_t2: i32) -> i32 {
  function _ffi_fn_test_weak (line 704) | extern "C" fn _ffi_fn_test_weak(weak: i32) -> i32 {
  function _ffi_fn_test_with (line 709) | extern "C" fn _ffi_fn_test_with(with: i32) -> i32 {
  function _ffi_fn_test_xor (line 714) | extern "C" fn _ffi_fn_test_xor(xor2: i32) -> i32 {
  function _ffi_fn_test_xor_eq (line 719) | extern "C" fn _ffi_fn_test_xor_eq(xor_eq2: i32) -> i32 {

FILE: src/tests/snapshots/cpp_demo_keyword_2024/ffi.h
  function namespace (line 7) | namespace rust {

FILE: src/tests/snapshots/cpp_demo_keyword_2024/miniffi.rs
  function _ffi_fn_rust_mem_leaked (line 4) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {
  function _ffi_fn_test_alignas (line 9) | extern "C" fn _ffi_fn_test_alignas(alignas2: i32) -> i32 {
  function _ffi_fn_test_alignof (line 14) | extern "C" fn _ffi_fn_test_alignof(alignof2: i32) -> i32 {
  function _ffi_fn_test_and (line 19) | extern "C" fn _ffi_fn_test_and(and2: i32) -> i32 {
  function _ffi_fn_test_and_eq (line 24) | extern "C" fn _ffi_fn_test_and_eq(and_eq2: i32) -> i32 {
  function _ffi_fn_test_asm (line 29) | extern "C" fn _ffi_fn_test_asm(asm2: i32) -> i32 {
  function _ffi_fn_test_associatedtype (line 34) | extern "C" fn _ffi_fn_test_associatedtype(associatedtype: i32) -> i32 {
  function _ffi_fn_test_associativity (line 39) | extern "C" fn _ffi_fn_test_associativity(associativity: i32) -> i32 {
  function _ffi_fn_test_atomic_cancel (line 44) | extern "C" fn _ffi_fn_test_atomic_cancel(atomic_cancel2: i32) -> i32 {
  function _ffi_fn_test_atomic_commit (line 49) | extern "C" fn _ffi_fn_test_atomic_commit(atomic_commit2: i32) -> i32 {
  function _ffi_fn_test_atomic_noexcept (line 54) | extern "C" fn _ffi_fn_test_atomic_noexcept(atomic_noexcept2: i32) -> i32 {
  function _ffi_fn_test_auto (line 59) | extern "C" fn _ffi_fn_test_auto(auto2: i32) -> i32 {
  function _ffi_fn_test_bitand (line 64) | extern "C" fn _ffi_fn_test_bitand(bitand2: i32) -> i32 {
  function _ffi_fn_test_bitor (line 69) | extern "C" fn _ffi_fn_test_bitor(bitor2: i32) -> i32 {
  function _ffi_fn_test_bool (line 74) | extern "C" fn _ffi_fn_test_bool(bool2: i32) -> i32 {
  function _ffi_fn_test_boolean (line 79) | extern "C" fn _ffi_fn_test_boolean(boolean: i32) -> i32 {
  function _ffi_fn_test_borrowing (line 84) | extern "C" fn _ffi_fn_test_borrowing(borrowing: i32) -> i32 {
  function _ffi_fn_test_byte (line 89) | extern "C" fn _ffi_fn_test_byte(byte: i32) -> i32 {
  function _ffi_fn_test_case (line 94) | extern "C" fn _ffi_fn_test_case(case2: i32) -> i32 {
  function _ffi_fn_test_catch (line 99) | extern "C" fn _ffi_fn_test_catch(catch2: i32) -> i32 {
  function _ffi_fn_test_char (line 104) | extern "C" fn _ffi_fn_test_char(char2: i32) -> i32 {
  function _ffi_fn_test_char16_t (line 109) | extern "C" fn _ffi_fn_test_char16_t(char16_t2: i32) -> i32 {
  function _ffi_fn_test_char32_t (line 114) | extern "C" fn _ffi_fn_test_char32_t(char32_t2: i32) -> i32 {
  function _ffi_fn_test_char8_t (line 119) | extern "C" fn _ffi_fn_test_char8_t(char8_t2: i32) -> i32 {
  function _ffi_fn_test_class (line 124) | extern "C" fn _ffi_fn_test_class(class2: i32) -> i32 {
  function _ffi_fn_test_co_await (line 129) | extern "C" fn _ffi_fn_test_co_await(co_await2: i32) -> i32 {
  function _ffi_fn_test_co_return (line 134) | extern "C" fn _ffi_fn_test_co_return(co_return2: i32) -> i32 {
  function _ffi_fn_test_co_yield (line 139) | extern "C" fn _ffi_fn_test_co_yield(co_yield2: i32) -> i32 {
  function _ffi_fn_test_compl (line 144) | extern "C" fn _ffi_fn_test_compl(compl2: i32) -> i32 {
  function _ffi_fn_test_concept (line 149) | extern "C" fn _ffi_fn_test_concept(concept2: i32) -> i32 {
  function _ffi_fn_test_const_cast (line 154) | extern "C" fn _ffi_fn_test_const_cast(const_cast2: i32) -> i32 {
  function _ffi_fn_test_consteval (line 159) | extern "C" fn _ffi_fn_test_consteval(consteval2: i32) -> i32 {
  function _ffi_fn_test_constexpr (line 164) | extern "C" fn _ffi_fn_test_constexpr(constexpr2: i32) -> i32 {
  function _ffi_fn_test_constinit (line 169) | extern "C" fn _ffi_fn_test_constinit(constinit2: i32) -> i32 {
  function _ffi_fn_test_consuming (line 174) | extern "C" fn _ffi_fn_test_consuming(consuming: i32) -> i32 {
  function _ffi_fn_test_contract_assert (line 179) | extern "C" fn _ffi_fn_test_contract_assert(contract_assert2: i32) -> i32 {
  function _ffi_fn_test_convenience (line 184) | extern "C" fn _ffi_fn_test_convenience(convenience: i32) -> i32 {
  function _ffi_fn_test_debugger (line 189) | extern "C" fn _ffi_fn_test_debugger(debugger: i32) -> i32 {
  function _ffi_fn_test_decltype (line 194) | extern "C" fn _ffi_fn_test_decltype(decltype2: i32) -> i32 {
  function _ffi_fn_test_default (line 199) | extern "C" fn _ffi_fn_test_default(default2: i32) -> i32 {
  function _ffi_fn_test_defer (line 204) | extern "C" fn _ffi_fn_test_defer(defer: i32) -> i32 {
  function _ffi_fn_test_deinit (line 209) | extern "C" fn _ffi_fn_test_deinit(deinit: i32) -> i32 {
  function _ffi_fn_test_delete (line 214) | extern "C" fn _ffi_fn_test_delete(delete2: i32) -> i32 {
  function _ffi_fn_test_double (line 219) | extern "C" fn _ffi_fn_test_double(double2: i32) -> i32 {
  function _ffi_fn_test_dynamic (line 224) | extern "C" fn _ffi_fn_test_dynamic(dynamic: i32) -> i32 {
  function _ffi_fn_test_dynamic_cast (line 229) | extern "C" fn _ffi_fn_test_dynamic_cast(dynamic_cast2: i32) -> i32 {
  function _ffi_fn_test_explicit (line 234) | extern "C" fn _ffi_fn_test_explicit(explicit2: i32) -> i32 {
  function _ffi_fn_test_export (line 239) | extern "C" fn _ffi_fn_test_export(export2: i32) -> i32 {
  function _ffi_fn_test_extends (line 244) | extern "C" fn _ffi_fn_test_extends(extends: i32) -> i32 {
  function _ffi_fn_test_extension (line 249) | extern "C" fn _ffi_fn_test_extension(extension: i32) -> i32 {
  function _ffi_fn_test_fallthrough (line 254) | extern "C" fn _ffi_fn_test_fallthrough(fallthrough: i32) -> i32 {
  function _ffi_fn_test_fileprivate (line 259) | extern "C" fn _ffi_fn_test_fileprivate(fileprivate: i32) -> i32 {
  function _ffi_fn_test_finally (line 264) | extern "C" fn _ffi_fn_test_finally(finally: i32) -> i32 {
  function _ffi_fn_test_float (line 269) | extern "C" fn _ffi_fn_test_float(float2: i32) -> i32 {
  function _ffi_fn_test_friend (line 274) | extern "C" fn _ffi_fn_test_friend(friend2: i32) -> i32 {
  function _ffi_fn_test_func (line 279) | extern "C" fn _ffi_fn_test_func(func: i32) -> i32 {
  function _ffi_fn_test_function (line 284) | extern "C" fn _ffi_fn_test_function(function: i32) -> i32 {
  function _ffi_fn_test_get (line 289) | extern "C" fn _ffi_fn_test_get(get: i32) -> i32 {
  function _ffi_fn_test_goto (line 294) | extern "C" fn _ffi_fn_test_goto(goto2: i32) -> i32 {
  function _ffi_fn_test_guard (line 299) | extern "C" fn _ffi_fn_test_guard(guard: i32) -> i32 {
  function _ffi_fn_test_implements (line 304) | extern "C" fn _ffi_fn_test_implements(implements: i32) -> i32 {
  function _ffi_fn_test_import (line 309) | extern "C" fn _ffi_fn_test_import(import: i32) -> i32 {
  function _ffi_fn_test_indirect (line 314) | extern "C" fn _ffi_fn_test_indirect(indirect: i32) -> i32 {
  function _ffi_fn_test_infix (line 319) | extern "C" fn _ffi_fn_test_infix(infix: i32) -> i32 {
  function _ffi_fn_test_init (line 324) | extern "C" fn _ffi_fn_test_init(init: i32) -> i32 {
  function _ffi_fn_test_inline (line 329) | extern "C" fn _ffi_fn_test_inline(inline2: i32) -> i32 {
  function _ffi_fn_test_inout (line 334) | extern "C" fn _ffi_fn_test_inout(inout: i32) -> i32 {
  function _ffi_fn_test_instanceof (line 339) | extern "C" fn _ffi_fn_test_instanceof(instanceof: i32) -> i32 {
  function _ffi_fn_test_int (line 344) | extern "C" fn _ffi_fn_test_int(int2: i32) -> i32 {
  function _ffi_fn_test_interface (line 349) | extern "C" fn _ffi_fn_test_interface(interface: i32) -> i32 {
  function _ffi_fn_test_internal (line 354) | extern "C" fn _ffi_fn_test_internal(internal: i32) -> i32 {
  function _ffi_fn_test_is (line 359) | extern "C" fn _ffi_fn_test_is(is: i32) -> i32 {
  function _ffi_fn_test_lazy (line 364) | extern "C" fn _ffi_fn_test_lazy(lazy: i32) -> i32 {
  function _ffi_fn_test_left (line 369) | extern "C" fn _ffi_fn_test_left(left: i32) -> i32 {
  function _ffi_fn_test_long (line 374) | extern "C" fn _ffi_fn_test_long(long2: i32) -> i32 {
  function _ffi_fn_test_mutable (line 379) | extern "C" fn _ffi_fn_test_mutable(mutable2: i32) -> i32 {
  function _ffi_fn_test_mutating (line 384) | extern "C" fn _ffi_fn_test_mutating(mutating: i32) -> i32 {
  function _ffi_fn_test_namespace (line 389) | extern "C" fn _ffi_fn_test_namespace(namespace2: i32) -> i32 {
  function _ffi_fn_test_native (line 394) | extern "C" fn _ffi_fn_test_native(native: i32) -> i32 {
  function _ffi_fn_test_new (line 399) | extern "C" fn _ffi_fn_test_new(new2: i32) -> i32 {
  function _ffi_fn_test_nil (line 404) | extern "C" fn _ffi_fn_test_nil(nil: i32) -> i32 {
  function _ffi_fn_test_noexcept (line 409) | extern "C" fn _ffi_fn_test_noexcept(noexcept2: i32) -> i32 {
  function _ffi_fn_test_none (line 414) | extern "C" fn _ffi_fn_test_none(none: i32) -> i32 {
  function _ffi_fn_test_nonisolated (line 419) | extern "C" fn _ffi_fn_test_nonisolated(nonisolated: i32) -> i32 {
  function _ffi_fn_test_nonmutating (line 424) | extern "C" fn _ffi_fn_test_nonmutating(nonmutating: i32) -> i32 {
  function _ffi_fn_test_not (line 429) | extern "C" fn _ffi_fn_test_not(not2: i32) -> i32 {
  function _ffi_fn_test_not_eq (line 434) | extern "C" fn _ffi_fn_test_not_eq(not_eq2: i32) -> i32 {
  function _ffi_fn_test_null (line 439) | extern "C" fn _ffi_fn_test_null(null: i32) -> i32 {
  function _ffi_fn_test_nullptr (line 444) | extern "C" fn _ffi_fn_test_nullptr(nullptr2: i32) -> i32 {
  function _ffi_fn_test_open (line 449) | extern "C" fn _ffi_fn_test_open(open: i32) -> i32 {
  function _ffi_fn_test_operator (line 454) | extern "C" fn _ffi_fn_test_operator(operator2: i32) -> i32 {
  function _ffi_fn_test_optional (line 459) | extern "C" fn _ffi_fn_test_optional(optional: i32) -> i32 {
  function _ffi_fn_test_or (line 464) | extern "C" fn _ffi_fn_test_or(or2: i32) -> i32 {
  function _ffi_fn_test_or_eq (line 469) | extern "C" fn _ffi_fn_test_or_eq(or_eq2: i32) -> i32 {
  function _ffi_fn_test_package (line 474) | extern "C" fn _ffi_fn_test_package(package: i32) -> i32 {
  function _ffi_fn_test_postfix (line 479) | extern "C" fn _ffi_fn_test_postfix(postfix: i32) -> i32 {
  function _ffi_fn_test_precedence (line 484) | extern "C" fn _ffi_fn_test_precedence(precedence: i32) -> i32 {
  function _ffi_fn_test_precedencegroup (line 489) | extern "C" fn _ffi_fn_test_precedencegroup(precedencegroup: i32) -> i32 {
  function _ffi_fn_test_prefix (line 494) | extern "C" fn _ffi_fn_test_prefix(prefix: i32) -> i32 {
  function _ffi_fn_test_private (line 499) | extern "C" fn _ffi_fn_test_private(private2: i32) -> i32 {
  function _ffi_fn_test_protected (line 504) | extern "C" fn _ffi_fn_test_protected(protected2: i32) -> i32 {
  function _ffi_fn_test_protocol (line 509) | extern "C" fn _ffi_fn_test_protocol(protocol: i32) -> i32 {
  function _ffi_fn_test_public (line 514) | extern "C" fn _ffi_fn_test_public(public2: i32) -> i32 {
  function _ffi_fn_test_reflexpr (line 519) | extern "C" fn _ffi_fn_test_reflexpr(reflexpr2: i32) -> i32 {
  function _ffi_fn_test_register (line 524) | extern "C" fn _ffi_fn_test_register(register2: i32) -> i32 {
  function _ffi_fn_test_reinterpret_cast (line 529) | extern "C" fn _ffi_fn_test_reinterpret_cast(reinterpret_cast2: i32) -> i...
  function _ffi_fn_test_repeat (line 534) | extern "C" fn _ffi_fn_test_repeat(repeat: i32) -> i32 {
  function _ffi_fn_test_required (line 539) | extern "C" fn _ffi_fn_test_required(required: i32) -> i32 {
  function _ffi_fn_test_requires (line 544) | extern "C" fn _ffi_fn_test_requires(requires2: i32) -> i32 {
  function _ffi_fn_test_rethrows (line 549) | extern "C" fn _ffi_fn_test_rethrows(rethrows: i32) -> i32 {
  function _ffi_fn_test_right (line 554) | extern "C" fn _ffi_fn_test_right(right: i32) -> i32 {
  function _ffi_fn_test_set (line 559) | extern "C" fn _ffi_fn_test_set(set: i32) -> i32 {
  function _ffi_fn_test_short (line 564) | extern "C" fn _ffi_fn_test_short(short2: i32) -> i32 {
  function _ffi_fn_test_signed (line 569) | extern "C" fn _ffi_fn_test_signed(signed2: i32) -> i32 {
  function _ffi_fn_test_sizeof (line 574) | extern "C" fn _ffi_fn_test_sizeof(sizeof2: i32) -> i32 {
  function _ffi_fn_test_some (line 579) | extern "C" fn _ffi_fn_test_some(some: i32) -> i32 {
  function _ffi_fn_test_static_assert (line 584) | extern "C" fn _ffi_fn_test_static_assert(static_assert2: i32) -> i32 {
  function _ffi_fn_test_static_cast (line 589) | extern "C" fn _ffi_fn_test_static_cast(static_cast2: i32) -> i32 {
  function _ffi_fn_test_subscript (line 594) | extern "C" fn _ffi_fn_test_subscript(subscript: i32) -> i32 {
  function _ffi_fn_test_switch (line 599) | extern "C" fn _ffi_fn_test_switch(switch2: i32) -> i32 {
  function _ffi_fn_test_synchronized (line 604) | extern "C" fn _ffi_fn_test_synchronized(synchronized2: i32) -> i32 {
  function _ffi_fn_test_template (line 609) | extern "C" fn _ffi_fn_test_template(template2: i32) -> i32 {
  function _ffi_fn_test_this (line 614) | extern "C" fn _ffi_fn_test_this(this2: i32) -> i32 {
  function _ffi_fn_test_thread_local (line 619) | extern "C" fn _ffi_fn_test_thread_local(thread_local2: i32) -> i32 {
  function _ffi_fn_test_throw (line 624) | extern "C" fn _ffi_fn_test_throw(throw2: i32) -> i32 {
  function _ffi_fn_test_throws (line 629) | extern "C" fn _ffi_fn_test_throws(throws: i32) -> i32 {
  function _ffi_fn_test_transient (line 634) | extern "C" fn _ffi_fn_test_transient(transient: i32) -> i32 {
  function _ffi_fn_test_typealias (line 639) | extern "C" fn _ffi_fn_test_typealias(typealias: i32) -> i32 {
  function _ffi_fn_test_typedef (line 644) | extern "C" fn _ffi_fn_test_typedef(typedef2: i32) -> i32 {
  function _ffi_fn_test_typeid (line 649) | extern "C" fn _ffi_fn_test_typeid(typeid2: i32) -> i32 {
  function _ffi_fn_test_typename (line 654) | extern "C" fn _ffi_fn_test_typename(typename2: i32) -> i32 {
  function _ffi_fn_test_undefined (line 659) | extern "C" fn _ffi_fn_test_undefined(undefined: i32) -> i32 {
  function _ffi_fn_test_union (line 664) | extern "C" fn _ffi_fn_test_union(union2: i32) -> i32 {
  function _ffi_fn_test_unowned (line 669) | extern "C" fn _ffi_fn_test_unowned(unowned: i32) -> i32 {
  function _ffi_fn_test_unsigned (line 674) | extern "C" fn _ffi_fn_test_unsigned(unsigned2: i32) -> i32 {
  function _ffi_fn_test_using (line 679) | extern "C" fn _ffi_fn_test_using(using2: i32) -> i32 {
  function _ffi_fn_test_var (line 684) | extern "C" fn _ffi_fn_test_var(var: i32) -> i32 {
  function _ffi_fn_test_void (line 689) | extern "C" fn _ffi_fn_test_void(void2: i32) -> i32 {
  function _ffi_fn_test_volatile (line 694) | extern "C" fn _ffi_fn_test_volatile(volatile2: i32) -> i32 {
  function _ffi_fn_test_wchar_t (line 699) | extern "C" fn _ffi_fn_test_wchar_t(wchar_t2: i32) -> i32 {
  function _ffi_fn_test_weak (line 704) | extern "C" fn _ffi_fn_test_weak(weak: i32) -> i32 {
  function _ffi_fn_test_with (line 709) | extern "C" fn _ffi_fn_test_with(with: i32) -> i32 {
  function _ffi_fn_test_xor (line 714) | extern "C" fn _ffi_fn_test_xor(xor2: i32) -> i32 {
  function _ffi_fn_test_xor_eq (line 719) | extern "C" fn _ffi_fn_test_xor_eq(xor_eq2: i32) -> i32 {

FILE: src/tests/snapshots/cpp_demo_order_2021/ffi.h
  function namespace (line 10) | namespace rust {
  type EarlyInsideStruct (line 35) | struct EarlyInsideStruct {
  function namespace (line 39) | namespace detail {
  type LaterInsideEnum (line 47) | struct LaterInsideEnum
  function namespace (line 55) | namespace detail {
  type EarlyOutsideEnum (line 63) | struct EarlyOutsideEnum
  type LaterInsideStruct (line 71) | struct LaterInsideStruct {
  type EarlyOutsideStruct (line 75) | struct EarlyOutsideStruct {
  function namespace (line 79) | namespace detail {
  type FirstEnum (line 87) | struct FirstEnum
  type FirstStruct (line 95) | struct FirstStruct {
  type FirstTrait (line 99) | struct FirstTrait {
  function namespace (line 104) | namespace detail {
  type LaterOutsideEnum (line 112) | struct LaterOutsideEnum
  type LaterOutsideStruct (line 120) | struct LaterOutsideStruct {
  function namespace (line 124) | namespace detail {
  type SecondEnum (line 132) | struct SecondEnum
  type SecondStruct (line 140) | struct SecondStruct {
  type SecondTrait (line 144) | struct SecondTrait {

FILE: src/tests/snapshots/cpp_demo_order_2021/miniffi.rs
  function _ffi_fn_rust_mem_leaked (line 4) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {

FILE: src/tests/snapshots/cpp_demo_order_2024/ffi.h
  function namespace (line 10) | namespace rust {
  type EarlyInsideStruct (line 35) | struct EarlyInsideStruct {
  function namespace (line 39) | namespace detail {
  type LaterInsideEnum (line 47) | struct LaterInsideEnum
  function namespace (line 55) | namespace detail {
  type EarlyOutsideEnum (line 63) | struct EarlyOutsideEnum
  type LaterInsideStruct (line 71) | struct LaterInsideStruct {
  type EarlyOutsideStruct (line 75) | struct EarlyOutsideStruct {
  function namespace (line 79) | namespace detail {
  type FirstEnum (line 87) | struct FirstEnum
  type FirstStruct (line 95) | struct FirstStruct {
  type FirstTrait (line 99) | struct FirstTrait {
  function namespace (line 104) | namespace detail {
  type LaterOutsideEnum (line 112) | struct LaterOutsideEnum
  type LaterOutsideStruct (line 120) | struct LaterOutsideStruct {
  function namespace (line 124) | namespace detail {
  type SecondEnum (line 132) | struct SecondEnum
  type SecondStruct (line 140) | struct SecondStruct {
  type SecondTrait (line 144) | struct SecondTrait {

FILE: src/tests/snapshots/cpp_demo_order_2024/miniffi.rs
  function _ffi_fn_rust_mem_leaked (line 4) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {

FILE: src/tests/snapshots/cpp_demo_trait_2021/ffi.cpp
  type _ffi_ret_ptr_2_usize (line 5) | struct _ffi_ret_ptr_2_usize {
  type _ffi_Box_Trait (line 26) | struct _ffi_Box_Trait final : rust::Trait {
    method _ffi_Box_Trait (line 27) | _ffi_Box_Trait(const void* ptr) : _self(ptr) {}
  type _ffi_Rc_Trait (line 33) | struct _ffi_Rc_Trait final : rust::Trait {
    method _ffi_Rc_Trait (line 34) | _ffi_Rc_Trait(const void* ptr) : _self(ptr) {}
  function T (line 46) | T _ffi_read(const uint8_t* &ptr) {
  function _ffi_string_from_rust (line 53) | std::string _ffi_string_from_rust(const char* ptr, uintptr_t len, uintpt...
  function _ffi_vec_box_dyn_Trait_from_rust (line 59) | std::vector<std::unique_ptr<rust::Trait>> _ffi_vec_box_dyn_Trait_from_ru...
  function _ffi_vec_rc_dyn_Trait_from_rust (line 70) | std::vector<std::shared_ptr<rust::Trait>> _ffi_vec_rc_dyn_Trait_from_rus...
  function _ffi_vec_Example_from_rust (line 81) | std::vector<rust::Example> _ffi_vec_Example_from_rust(uintptr_t len, con...
  function _ffi_write (line 110) | void _ffi_write(T val, std::vector<uint8_t> &buf) {
  function _ffi_vec_box_dyn_Trait_to_rust (line 114) | void _ffi_vec_box_dyn_Trait_to_rust(std::vector<std::unique_ptr<rust::Tr...
  function _ffi_vec_rc_dyn_Trait_to_rust (line 121) | void _ffi_vec_rc_dyn_Trait_to_rust(std::vector<std::shared_ptr<rust::Tra...
  function _ffi_vec_Example_to_rust (line 128) | void _ffi_vec_Example_to_rust(std::vector<rust::Example>&& items, std::v...
  function _ffi_cpp_Box_Trait__get (line 155) | int32_t _ffi_cpp_Box_Trait__get(rust::Trait* _self) {
  function _ffi_cpp_Rc_Trait__get (line 159) | int32_t _ffi_cpp_Rc_Trait__get(std::shared_ptr<rust::Trait>* _self) {
  function _ffi_cpp_drop_Box_Trait (line 163) | void _ffi_cpp_drop_Box_Trait(rust::Trait* self) {
  function _ffi_cpp_drop_Rc_Trait (line 167) | void _ffi_cpp_drop_Rc_Trait(std::shared_ptr<rust::Trait>* self) {

FILE: src/tests/snapshots/cpp_demo_trait_2021/ffi.h
  function namespace (line 10) | namespace rust {

FILE: src/tests/snapshots/cpp_demo_trait_2021/miniffi.rs
  function _ffi_Box_Trait__get (line 4) | extern "C" fn _ffi_Box_Trait__get(_self: *const u8) -> i32 {
  function _ffi_Rc_Trait__get (line 10) | extern "C" fn _ffi_Rc_Trait__get(_self: *const u8) -> i32 {
  function _ffi_alloc (line 16) | extern "C" fn _ffi_alloc(len: usize) -> *const u8 {
  function _ffi_buf_from_host (line 20) | fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) {
  function _ffi_dealloc (line 26) | extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) {
  function _ffi_buf_to_host (line 30) | fn _ffi_buf_to_host(buf: Vec<u8>) -> (*const u8, usize) {
  function _ffi_drop_Box_Trait (line 36) | extern "C" fn _ffi_drop_Box_Trait(ptr: *const u8) {
  function _ffi_drop_Rc_Trait (line 41) | extern "C" fn _ffi_drop_Rc_Trait(ptr: *const u8) {
  function _ffi_fn_rust_mem_leaked (line 46) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {
  function _ffi_fn_test (line 51) | extern "C" fn _ffi_fn_test(buf_ptr: *const u8, vec_len: usize) -> _ffi_r...
  function _ffi_read (line 62) | fn _ffi_read<T: Copy>(ptr: &mut *const u8) -> T {
  type _ffi_ret_ptr_2_usize (line 69) | struct _ffi_ret_ptr_2_usize(*const u8, usize, usize);
  type _ffi_rs_Box_Trait (line 72) | struct _ffi_rs_Box_Trait(*const u8);
  method drop (line 75) | fn drop(&mut self) {
  method get (line 82) | fn get(&self) -> i32 {
  type _ffi_rs_Rc_Trait (line 89) | struct _ffi_rs_Rc_Trait(*const u8);
  method drop (line 92) | fn drop(&mut self) {
  method get (line 99) | fn get(&self) -> i32 {
  function _ffi_string_from_host (line 105) | fn _ffi_string_from_host(ptr: *const u8, len: usize) -> String {
  function _ffi_string_to_host (line 109) | fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) {
  function _ffi_vec_Example_from_cpp (line 115) | fn _ffi_vec_Example_from_cpp(len: usize, end: &mut *const u8) -> Vec<Exa...
  function _ffi_vec_Example_to_cpp (line 130) | fn _ffi_vec_Example_to_cpp(items: Vec<Example>, buf: &mut Vec<u8>) {
  function _ffi_vec_box_dyn_Trait_from_cpp (line 146) | fn _ffi_vec_box_dyn_Trait_from_cpp(len: usize, end: &mut *const u8) -> V...
  function _ffi_vec_box_dyn_Trait_to_cpp (line 155) | fn _ffi_vec_box_dyn_Trait_to_cpp(items: Vec<Box<dyn Trait>>, buf: &mut V...
  function _ffi_vec_rc_dyn_Trait_from_cpp (line 162) | fn _ffi_vec_rc_dyn_Trait_from_cpp(len: usize, end: &mut *const u8) -> Ve...
  function _ffi_vec_rc_dyn_Trait_to_cpp (line 171) | fn _ffi_vec_rc_dyn_Trait_to_cpp(items: Vec<std::rc::Rc<dyn Trait>>, buf:...
  function _ffi_write (line 177) | fn _ffi_write<T: Copy>(val: T, buf: &mut Vec<u8>) {

FILE: src/tests/snapshots/cpp_demo_trait_2024/ffi.cpp
  type _ffi_ret_ptr_2_usize (line 5) | struct _ffi_ret_ptr_2_usize {
  type _ffi_Box_Trait (line 26) | struct _ffi_Box_Trait final : rust::Trait {
    method _ffi_Box_Trait (line 27) | _ffi_Box_Trait(const void* ptr) : _self(ptr) {}
  type _ffi_Rc_Trait (line 33) | struct _ffi_Rc_Trait final : rust::Trait {
    method _ffi_Rc_Trait (line 34) | _ffi_Rc_Trait(const void* ptr) : _self(ptr) {}
  function T (line 46) | T _ffi_read(const uint8_t* &ptr) {
  function _ffi_string_from_rust (line 53) | std::string _ffi_string_from_rust(const char* ptr, uintptr_t len, uintpt...
  function _ffi_vec_box_dyn_Trait_from_rust (line 59) | std::vector<std::unique_ptr<rust::Trait>> _ffi_vec_box_dyn_Trait_from_ru...
  function _ffi_vec_rc_dyn_Trait_from_rust (line 70) | std::vector<std::shared_ptr<rust::Trait>> _ffi_vec_rc_dyn_Trait_from_rus...
  function _ffi_vec_Example_from_rust (line 81) | std::vector<rust::Example> _ffi_vec_Example_from_rust(uintptr_t len, con...
  function _ffi_write (line 110) | void _ffi_write(T val, std::vector<uint8_t> &buf) {
  function _ffi_vec_box_dyn_Trait_to_rust (line 114) | void _ffi_vec_box_dyn_Trait_to_rust(std::vector<std::unique_ptr<rust::Tr...
  function _ffi_vec_rc_dyn_Trait_to_rust (line 121) | void _ffi_vec_rc_dyn_Trait_to_rust(std::vector<std::shared_ptr<rust::Tra...
  function _ffi_vec_Example_to_rust (line 128) | void _ffi_vec_Example_to_rust(std::vector<rust::Example>&& items, std::v...
  function _ffi_cpp_Box_Trait__get (line 155) | int32_t _ffi_cpp_Box_Trait__get(rust::Trait* _self) {
  function _ffi_cpp_Rc_Trait__get (line 159) | int32_t _ffi_cpp_Rc_Trait__get(std::shared_ptr<rust::Trait>* _self) {
  function _ffi_cpp_drop_Box_Trait (line 163) | void _ffi_cpp_drop_Box_Trait(rust::Trait* self) {
  function _ffi_cpp_drop_Rc_Trait (line 167) | void _ffi_cpp_drop_Rc_Trait(std::shared_ptr<rust::Trait>* self) {

FILE: src/tests/snapshots/cpp_demo_trait_2024/ffi.h
  function namespace (line 10) | namespace rust {

FILE: src/tests/snapshots/cpp_demo_trait_2024/miniffi.rs
  function _ffi_Box_Trait__get (line 4) | extern "C" fn _ffi_Box_Trait__get(_self: *const u8) -> i32 {
  function _ffi_Rc_Trait__get (line 10) | extern "C" fn _ffi_Rc_Trait__get(_self: *const u8) -> i32 {
  function _ffi_alloc (line 16) | extern "C" fn _ffi_alloc(len: usize) -> *const u8 {
  function _ffi_buf_from_host (line 20) | fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) {
  function _ffi_dealloc (line 26) | extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) {
  function _ffi_buf_to_host (line 30) | fn _ffi_buf_to_host(buf: Vec<u8>) -> (*const u8, usize) {
  function _ffi_drop_Box_Trait (line 36) | extern "C" fn _ffi_drop_Box_Trait(ptr: *const u8) {
  function _ffi_drop_Rc_Trait (line 41) | extern "C" fn _ffi_drop_Rc_Trait(ptr: *const u8) {
  function _ffi_fn_rust_mem_leaked (line 46) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {
  function _ffi_fn_test (line 51) | extern "C" fn _ffi_fn_test(buf_ptr: *const u8, vec_len: usize) -> _ffi_r...
  function _ffi_read (line 62) | fn _ffi_read<T: Copy>(ptr: &mut *const u8) -> T {
  type _ffi_ret_ptr_2_usize (line 69) | struct _ffi_ret_ptr_2_usize(*const u8, usize, usize);
  type _ffi_rs_Box_Trait (line 72) | struct _ffi_rs_Box_Trait(*const u8);
  method drop (line 75) | fn drop(&mut self) {
  method get (line 82) | fn get(&self) -> i32 {
  type _ffi_rs_Rc_Trait (line 89) | struct _ffi_rs_Rc_Trait(*const u8);
  method drop (line 92) | fn drop(&mut self) {
  method get (line 99) | fn get(&self) -> i32 {
  function _ffi_string_from_host (line 105) | fn _ffi_string_from_host(ptr: *const u8, len: usize) -> String {
  function _ffi_string_to_host (line 109) | fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) {
  function _ffi_vec_Example_from_cpp (line 115) | fn _ffi_vec_Example_from_cpp(len: usize, end: &mut *const u8) -> Vec<Exa...
  function _ffi_vec_Example_to_cpp (line 130) | fn _ffi_vec_Example_to_cpp(items: Vec<Example>, buf: &mut Vec<u8>) {
  function _ffi_vec_box_dyn_Trait_from_cpp (line 146) | fn _ffi_vec_box_dyn_Trait_from_cpp(len: usize, end: &mut *const u8) -> V...
  function _ffi_vec_box_dyn_Trait_to_cpp (line 155) | fn _ffi_vec_box_dyn_Trait_to_cpp(items: Vec<Box<dyn Trait>>, buf: &mut V...
  function _ffi_vec_rc_dyn_Trait_from_cpp (line 162) | fn _ffi_vec_rc_dyn_Trait_from_cpp(len: usize, end: &mut *const u8) -> Ve...
  function _ffi_vec_rc_dyn_Trait_to_cpp (line 171) | fn _ffi_vec_rc_dyn_Trait_to_cpp(items: Vec<std::rc::Rc<dyn Trait>>, buf:...
  function _ffi_write (line 177) | fn _ffi_write<T: Copy>(val: T, buf: &mut Vec<u8>) {

FILE: src/tests/snapshots/cpp_fn_basic_2021/ffi.h
  function namespace (line 7) | namespace rust {

FILE: src/tests/snapshots/cpp_fn_basic_2021/miniffi.rs
  function _ffi_fn_add_bool (line 4) | extern "C" fn _ffi_fn_add_bool(x: bool, y: bool) -> bool {
  function _ffi_fn_add_f32 (line 9) | extern "C" fn _ffi_fn_add_f32(x: f32, y: f32) -> f32 {
  function _ffi_fn_add_f64 (line 14) | extern "C" fn _ffi_fn_add_f64(x: f64, y: f64) -> f64 {
  function _ffi_fn_add_i16 (line 19) | extern "C" fn _ffi_fn_add_i16(x: i16, y: i16) -> i16 {
  function _ffi_fn_add_i32 (line 24) | extern "C" fn _ffi_fn_add_i32(x: i32, y: i32) -> i32 {
  function _ffi_fn_add_i64 (line 29) | extern "C" fn _ffi_fn_add_i64(x: i64, y: i64) -> i64 {
  function _ffi_fn_add_i8 (line 34) | extern "C" fn _ffi_fn_add_i8(x: i8, y: i8) -> i8 {
  function _ffi_fn_add_isize (line 39) | extern "C" fn _ffi_fn_add_isize(x: isize, y: isize) -> isize {
  function _ffi_fn_add_u16 (line 44) | extern "C" fn _ffi_fn_add_u16(x: u16, y: u16) -> u16 {
  function _ffi_fn_add_u32 (line 49) | extern "C" fn _ffi_fn_add_u32(x: u32, y: u32) -> u32 {
  function _ffi_fn_add_u64 (line 54) | extern "C" fn _ffi_fn_add_u64(x: u64, y: u64) -> u64 {
  function _ffi_fn_add_u8 (line 59) | extern "C" fn _ffi_fn_add_u8(x: u8, y: u8) -> u8 {
  function _ffi_fn_add_usize (line 64) | extern "C" fn _ffi_fn_add_usize(x: usize, y: usize) -> usize {
  function _ffi_fn_rust_mem_leaked (line 69) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {

FILE: src/tests/snapshots/cpp_fn_basic_2024/ffi.h
  function namespace (line 7) | namespace rust {

FILE: src/tests/snapshots/cpp_fn_basic_2024/miniffi.rs
  function _ffi_fn_add_bool (line 4) | extern "C" fn _ffi_fn_add_bool(x: bool, y: bool) -> bool {
  function _ffi_fn_add_f32 (line 9) | extern "C" fn _ffi_fn_add_f32(x: f32, y: f32) -> f32 {
  function _ffi_fn_add_f64 (line 14) | extern "C" fn _ffi_fn_add_f64(x: f64, y: f64) -> f64 {
  function _ffi_fn_add_i16 (line 19) | extern "C" fn _ffi_fn_add_i16(x: i16, y: i16) -> i16 {
  function _ffi_fn_add_i32 (line 24) | extern "C" fn _ffi_fn_add_i32(x: i32, y: i32) -> i32 {
  function _ffi_fn_add_i64 (line 29) | extern "C" fn _ffi_fn_add_i64(x: i64, y: i64) -> i64 {
  function _ffi_fn_add_i8 (line 34) | extern "C" fn _ffi_fn_add_i8(x: i8, y: i8) -> i8 {
  function _ffi_fn_add_isize (line 39) | extern "C" fn _ffi_fn_add_isize(x: isize, y: isize) -> isize {
  function _ffi_fn_add_u16 (line 44) | extern "C" fn _ffi_fn_add_u16(x: u16, y: u16) -> u16 {
  function _ffi_fn_add_u32 (line 49) | extern "C" fn _ffi_fn_add_u32(x: u32, y: u32) -> u32 {
  function _ffi_fn_add_u64 (line 54) | extern "C" fn _ffi_fn_add_u64(x: u64, y: u64) -> u64 {
  function _ffi_fn_add_u8 (line 59) | extern "C" fn _ffi_fn_add_u8(x: u8, y: u8) -> u8 {
  function _ffi_fn_add_usize (line 64) | extern "C" fn _ffi_fn_add_usize(x: usize, y: usize) -> usize {
  function _ffi_fn_rust_mem_leaked (line 69) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {

FILE: src/tests/snapshots/cpp_fn_basic_void_2021/ffi.h
  function namespace (line 8) | namespace rust {

FILE: src/tests/snapshots/cpp_fn_basic_void_2021/miniffi.rs
  function _ffi_fn_add_empty_tuple (line 4) | extern "C" fn _ffi_fn_add_empty_tuple(x: i32, y: i32) {
  function _ffi_fn_add_void (line 9) | extern "C" fn _ffi_fn_add_void(x: i32, y: i32) {
  function _ffi_fn_get_result (line 14) | extern "C" fn _ffi_fn_get_result() -> i32 {
  function _ffi_fn_rust_mem_leaked (line 19) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {
  function _ffi_fn_wild_arg (line 24) | extern "C" fn _ffi_fn_wild_arg(_1: i32, _3: i32) {

FILE: src/tests/snapshots/cpp_fn_basic_void_2024/ffi.h
  function namespace (line 8) | namespace rust {

FILE: src/tests/snapshots/cpp_fn_basic_void_2024/miniffi.rs
  function _ffi_fn_add_empty_tuple (line 4) | extern "C" fn _ffi_fn_add_empty_tuple(x: i32, y: i32) {
  function _ffi_fn_add_void (line 9) | extern "C" fn _ffi_fn_add_void(x: i32, y: i32) {
  function _ffi_fn_get_result (line 14) | extern "C" fn _ffi_fn_get_result() -> i32 {
  function _ffi_fn_rust_mem_leaked (line 19) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {
  function _ffi_fn_wild_arg (line 24) | extern "C" fn _ffi_fn_wild_arg(_1: i32, _3: i32) {

FILE: src/tests/snapshots/cpp_fn_box_in_2021/ffi.cpp
  function _ffi_write (line 18) | void _ffi_write(T val, std::vector<uint8_t> &buf) {
  function _ffi_box_i32_to_rust (line 22) | void _ffi_box_i32_to_rust(int32_t val, std::vector<uint8_t>& buf) {
  function _ffi_box_box_i32_to_rust (line 26) | void _ffi_box_box_i32_to_rust(std::unique_ptr<int32_t> val, std::vector<...
  function _ffi_box_box_box_i32_to_rust (line 30) | void _ffi_box_box_box_i32_to_rust(std::unique_ptr<std::unique_ptr<int32_...
  function _ffi_box_Tree_to_rust (line 40) | void _ffi_box_Tree_to_rust(rust::Tree val, std::vector<uint8_t>& buf) {

FILE: src/tests/snapshots/cpp_fn_box_in_2021/ffi.h
  function namespace (line 9) | namespace rust {

FILE: src/tests/snapshots/cpp_fn_box_in_2021/miniffi.rs
  function _ffi_box_Tree_from_cpp (line 4) | fn _ffi_box_Tree_from_cpp(end: &mut *const u8) -> Box<Tree> {
  function _ffi_box_box_box_i32_from_cpp (line 12) | fn _ffi_box_box_box_i32_from_cpp(end: &mut *const u8) -> Box<Box<Box<i32...
  function _ffi_box_box_i32_from_cpp (line 16) | fn _ffi_box_box_i32_from_cpp(end: &mut *const u8) -> Box<Box<i32>> {
  function _ffi_box_i32_from_cpp (line 20) | fn _ffi_box_i32_from_cpp(end: &mut *const u8) -> Box<i32> {
  function _ffi_alloc (line 25) | extern "C" fn _ffi_alloc(len: usize) -> *const u8 {
  function _ffi_buf_from_host (line 29) | fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) {
  function _ffi_fn_check_nested (line 35) | extern "C" fn _ffi_fn_check_nested(buf_ptr: *const u8) -> i32 {
  function _ffi_fn_rust_mem_leaked (line 43) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {
  function _ffi_fn_sum_tree (line 48) | extern "C" fn _ffi_fn_sum_tree(tree_value: i32, buf_ptr: *const u8, has_...
  function _ffi_read (line 59) | fn _ffi_read<T: Copy>(ptr: &mut *const u8) -> T {

FILE: src/tests/snapshots/cpp_fn_box_in_2024/ffi.cpp
  function _ffi_write (line 18) | void _ffi_write(T val, std::vector<uint8_t> &buf) {
  function _ffi_box_i32_to_rust (line 22) | void _ffi_box_i32_to_rust(int32_t val, std::vector<uint8_t>& buf) {
  function _ffi_box_box_i32_to_rust (line 26) | void _ffi_box_box_i32_to_rust(std::unique_ptr<int32_t> val, std::vector<...
  function _ffi_box_box_box_i32_to_rust (line 30) | void _ffi_box_box_box_i32_to_rust(std::unique_ptr<std::unique_ptr<int32_...
  function _ffi_box_Tree_to_rust (line 40) | void _ffi_box_Tree_to_rust(rust::Tree val, std::vector<uint8_t>& buf) {

FILE: src/tests/snapshots/cpp_fn_box_in_2024/ffi.h
  function namespace (line 9) | namespace rust {

FILE: src/tests/snapshots/cpp_fn_box_in_2024/miniffi.rs
  function _ffi_box_Tree_from_cpp (line 4) | fn _ffi_box_Tree_from_cpp(end: &mut *const u8) -> Box<Tree> {
  function _ffi_box_box_box_i32_from_cpp (line 12) | fn _ffi_box_box_box_i32_from_cpp(end: &mut *const u8) -> Box<Box<Box<i32...
  function _ffi_box_box_i32_from_cpp (line 16) | fn _ffi_box_box_i32_from_cpp(end: &mut *const u8) -> Box<Box<i32>> {
  function _ffi_box_i32_from_cpp (line 20) | fn _ffi_box_i32_from_cpp(end: &mut *const u8) -> Box<i32> {
  function _ffi_alloc (line 25) | extern "C" fn _ffi_alloc(len: usize) -> *const u8 {
  function _ffi_buf_from_host (line 29) | fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) {
  function _ffi_fn_check_nested (line 35) | extern "C" fn _ffi_fn_check_nested(buf_ptr: *const u8) -> i32 {
  function _ffi_fn_rust_mem_leaked (line 43) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {
  function _ffi_fn_sum_tree (line 48) | extern "C" fn _ffi_fn_sum_tree(tree_value: i32, buf_ptr: *const u8, has_...
  function _ffi_read (line 59) | fn _ffi_read<T: Copy>(ptr: &mut *const u8) -> T {

FILE: src/tests/snapshots/cpp_fn_box_out_2021/ffi.cpp
  type _ffi_ret_i32_ptr_usize_2_bool (line 5) | struct _ffi_ret_i32_ptr_usize_2_bool {
  type _ffi_ret_ptr_usize (line 13) | struct _ffi_ret_ptr_usize {
  function T (line 30) | T _ffi_read(const uint8_t* &ptr) {
  function _ffi_box_i32_from_rust (line 37) | std::unique_ptr<int32_t> _ffi_box_i32_from_rust(const uint8_t*& end) {
  function _ffi_box_box_i32_from_rust (line 42) | std::unique_ptr<std::unique_ptr<int32_t>> _ffi_box_box_i32_from_rust(con...
  function _ffi_box_box_box_i32_from_rust (line 47) | std::unique_ptr<std::unique_ptr<std::unique_ptr<int32_t>>> _ffi_box_box_...
  function _ffi_box_Tree_from_rust (line 54) | std::unique_ptr<rust::Tree> _ffi_box_Tree_from_rust(const uint8_t*& end) {

FILE: src/tests/snapshots/cpp_fn_box_out_2021/ffi.h
  function namespace (line 9) | namespace rust {

FILE: src/tests/snapshots/cpp_fn_box_out_2021/miniffi.rs
  function _ffi_box_Tree_to_cpp (line 4) | fn _ffi_box_Tree_to_cpp(val: Tree, buf: &mut Vec<u8>) {
  function _ffi_box_box_box_i32_to_cpp (line 16) | fn _ffi_box_box_box_i32_to_cpp(val: Box<Box<i32>>, buf: &mut Vec<u8>) {
  function _ffi_box_box_i32_to_cpp (line 20) | fn _ffi_box_box_i32_to_cpp(val: Box<i32>, buf: &mut Vec<u8>) {
  function _ffi_box_i32_to_cpp (line 24) | fn _ffi_box_i32_to_cpp(val: i32, buf: &mut Vec<u8>) {
  function _ffi_dealloc (line 29) | extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) {
  function _ffi_buf_to_host (line 33) | fn _ffi_buf_to_host(buf: Vec<u8>) -> (*const u8, usize) {
  function _ffi_fn_check_nested (line 39) | extern "C" fn _ffi_fn_check_nested(x: i32) -> _ffi_ret_ptr_usize {
  function _ffi_fn_get_tree (line 49) | extern "C" fn _ffi_fn_get_tree() -> _ffi_ret_i32_ptr_usize_2_bool {
  function _ffi_fn_rust_mem_leaked (line 68) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {
  type _ffi_ret_i32_ptr_usize_2_bool (line 73) | struct _ffi_ret_i32_ptr_usize_2_bool(i32, *const u8, usize, bool, bool);
  type _ffi_ret_ptr_usize (line 76) | struct _ffi_ret_ptr_usize(*const u8, usize);
  function _ffi_write (line 78) | fn _ffi_write<T: Copy>(val: T, buf: &mut Vec<u8>) {

FILE: src/tests/snapshots/cpp_fn_box_out_2024/ffi.cpp
  type _ffi_ret_i32_ptr_usize_2_bool (line 5) | struct _ffi_ret_i32_ptr_usize_2_bool {
  type _ffi_ret_ptr_usize (line 13) | struct _ffi_ret_ptr_usize {
  function T (line 30) | T _ffi_read(const uint8_t* &ptr) {
  function _ffi_box_i32_from_rust (line 37) | std::unique_ptr<int32_t> _ffi_box_i32_from_rust(const uint8_t*& end) {
  function _ffi_box_box_i32_from_rust (line 42) | std::unique_ptr<std::unique_ptr<int32_t>> _ffi_box_box_i32_from_rust(con...
  function _ffi_box_box_box_i32_from_rust (line 47) | std::unique_ptr<std::unique_ptr<std::unique_ptr<int32_t>>> _ffi_box_box_...
  function _ffi_box_Tree_from_rust (line 54) | std::unique_ptr<rust::Tree> _ffi_box_Tree_from_rust(const uint8_t*& end) {

FILE: src/tests/snapshots/cpp_fn_box_out_2024/ffi.h
  function namespace (line 9) | namespace rust {

FILE: src/tests/snapshots/cpp_fn_box_out_2024/miniffi.rs
  function _ffi_box_Tree_to_cpp (line 4) | fn _ffi_box_Tree_to_cpp(val: Tree, buf: &mut Vec<u8>) {
  function _ffi_box_box_box_i32_to_cpp (line 16) | fn _ffi_box_box_box_i32_to_cpp(val: Box<Box<i32>>, buf: &mut Vec<u8>) {
  function _ffi_box_box_i32_to_cpp (line 20) | fn _ffi_box_box_i32_to_cpp(val: Box<i32>, buf: &mut Vec<u8>) {
  function _ffi_box_i32_to_cpp (line 24) | fn _ffi_box_i32_to_cpp(val: i32, buf: &mut Vec<u8>) {
  function _ffi_dealloc (line 29) | extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) {
  function _ffi_buf_to_host (line 33) | fn _ffi_buf_to_host(buf: Vec<u8>) -> (*const u8, usize) {
  function _ffi_fn_check_nested (line 39) | extern "C" fn _ffi_fn_check_nested(x: i32) -> _ffi_ret_ptr_usize {
  function _ffi_fn_get_tree (line 49) | extern "C" fn _ffi_fn_get_tree() -> _ffi_ret_i32_ptr_usize_2_bool {
  function _ffi_fn_rust_mem_leaked (line 68) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {
  type _ffi_ret_i32_ptr_usize_2_bool (line 73) | struct _ffi_ret_i32_ptr_usize_2_bool(i32, *const u8, usize, bool, bool);
  type _ffi_ret_ptr_usize (line 76) | struct _ffi_ret_ptr_usize(*const u8, usize);
  function _ffi_write (line 78) | fn _ffi_write<T: Copy>(val: T, buf: &mut Vec<u8>) {

FILE: src/tests/snapshots/cpp_fn_combo_in_2021/ffi.cpp
  type _ffi_ret_ptr_2_usize (line 5) | struct _ffi_ret_ptr_2_usize {
  function _ffi_string_from_rust (line 22) | std::string _ffi_string_from_rust(const char* ptr, uintptr_t len, uintpt...
  function _ffi_write (line 33) | void _ffi_write(T val, std::vector<uint8_t> &buf) {
  function _ffi_vec__i32_f32_bool_to_rust (line 37) | void _ffi_vec__i32_f32_bool_to_rust(std::vector<std::tuple<std::tuple<>,...
  function _ffi_vec_Foo_to_rust (line 46) | void _ffi_vec_Foo_to_rust(std::vector<rust::Foo>&& items, std::vector<ui...
  function _ffi_vec_Bar_to_rust (line 61) | void _ffi_vec_Bar_to_rust(std::vector<rust::Bar>&& items, std::vector<ui...

FILE: src/tests/snapshots/cpp_fn_combo_in_2021/ffi.h
  function namespace (line 10) | namespace rust {

FILE: src/tests/snapshots/cpp_fn_combo_in_2021/miniffi.rs
  function _ffi_alloc (line 4) | extern "C" fn _ffi_alloc(len: usize) -> *const u8 {
  function _ffi_buf_from_host (line 8) | fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) {
  function _ffi_fn_check_combo (line 14) | extern "C" fn _ffi_fn_check_combo(foo_x_0_x: i32, buf_ptr: *const u8, fo...
  function _ffi_fn_rust_mem_leaked (line 28) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {
  function _ffi_read (line 32) | fn _ffi_read<T: Copy>(ptr: &mut *const u8) -> T {
  type _ffi_ret_ptr_2_usize (line 39) | struct _ffi_ret_ptr_2_usize(*const u8, usize, usize);
  function _ffi_dealloc (line 42) | extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) {
  function _ffi_string_to_host (line 46) | fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) {
  function _ffi_vec_Bar_from_cpp (line 52) | fn _ffi_vec_Bar_from_cpp(len: usize, end: &mut *const u8) -> Vec<Bar> {
  function _ffi_vec_Foo_from_cpp (line 61) | fn _ffi_vec_Foo_from_cpp(len: usize, end: &mut *const u8) -> Vec<Foo> {
  function _ffi_vec__i32_f32_bool_from_cpp (line 76) | fn _ffi_vec__i32_f32_bool_from_cpp(len: usize, end: &mut *const u8) -> V...

FILE: src/tests/snapshots/cpp_fn_combo_in_2024/ffi.cpp
  type _ffi_ret_ptr_2_usize (line 5) | struct _ffi_ret_ptr_2_usize {
  function _ffi_string_from_rust (line 22) | std::string _ffi_string_from_rust(const char* ptr, uintptr_t len, uintpt...
  function _ffi_write (line 33) | void _ffi_write(T val, std::vector<uint8_t> &buf) {
  function _ffi_vec__i32_f32_bool_to_rust (line 37) | void _ffi_vec__i32_f32_bool_to_rust(std::vector<std::tuple<std::tuple<>,...
  function _ffi_vec_Foo_to_rust (line 46) | void _ffi_vec_Foo_to_rust(std::vector<rust::Foo>&& items, std::vector<ui...
  function _ffi_vec_Bar_to_rust (line 61) | void _ffi_vec_Bar_to_rust(std::vector<rust::Bar>&& items, std::vector<ui...

FILE: src/tests/snapshots/cpp_fn_combo_in_2024/ffi.h
  function namespace (line 10) | namespace rust {

FILE: src/tests/snapshots/cpp_fn_combo_in_2024/miniffi.rs
  function _ffi_alloc (line 4) | extern "C" fn _ffi_alloc(len: usize) -> *const u8 {
  function _ffi_buf_from_host (line 8) | fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) {
  function _ffi_fn_check_combo (line 14) | extern "C" fn _ffi_fn_check_combo(foo_x_0_x: i32, buf_ptr: *const u8, fo...
  function _ffi_fn_rust_mem_leaked (line 28) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {
  function _ffi_read (line 32) | fn _ffi_read<T: Copy>(ptr: &mut *const u8) -> T {
  type _ffi_ret_ptr_2_usize (line 39) | struct _ffi_ret_ptr_2_usize(*const u8, usize, usize);
  function _ffi_dealloc (line 42) | extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) {
  function _ffi_string_to_host (line 46) | fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) {
  function _ffi_vec_Bar_from_cpp (line 52) | fn _ffi_vec_Bar_from_cpp(len: usize, end: &mut *const u8) -> Vec<Bar> {
  function _ffi_vec_Foo_from_cpp (line 61) | fn _ffi_vec_Foo_from_cpp(len: usize, end: &mut *const u8) -> Vec<Foo> {
  function _ffi_vec__i32_f32_bool_from_cpp (line 76) | fn _ffi_vec__i32_f32_bool_from_cpp(len: usize, end: &mut *const u8) -> V...

FILE: src/tests/snapshots/cpp_fn_combo_out_2021/ffi.cpp
  type _ffi_ret_i32_ptr_4_usize (line 5) | struct _ffi_ret_i32_ptr_4_usize {
  function T (line 26) | T _ffi_read(const uint8_t* &ptr) {
  function _ffi_vec__i32_f32_bool_from_rust (line 37) | std::vector<std::tuple<std::tuple<>, std::tuple<int32_t>, std::tuple<flo...
  function _ffi_vec_Foo_from_rust (line 53) | std::vector<rust::Foo> _ffi_vec_Foo_from_rust(uintptr_t len, const uint8...
  function _ffi_vec_Bar_from_rust (line 72) | std::vector<rust::Bar> _ffi_vec_Bar_from_rust(uintptr_t len, const uint8...

FILE: src/tests/snapshots/cpp_fn_combo_out_2021/ffi.h
  function namespace (line 9) | namespace rust {

FILE: src/tests/snapshots/cpp_fn_combo_out_2021/miniffi.rs
  function _ffi_dealloc (line 4) | extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) {
  function _ffi_buf_to_host (line 8) | fn _ffi_buf_to_host(buf: Vec<u8>) -> (*const u8, usize) {
  function _ffi_fn_check_combo1 (line 14) | extern "C" fn _ffi_fn_check_combo1() -> _ffi_ret_i32_ptr_4_usize {
  function _ffi_fn_check_combo2 (line 34) | extern "C" fn _ffi_fn_check_combo2() -> _ffi_ret_i32_ptr_4_usize {
  function _ffi_fn_rust_mem_leaked (line 54) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {
  type _ffi_ret_i32_ptr_4_usize (line 59) | struct _ffi_ret_i32_ptr_4_usize(i32, *const u8, usize, usize, usize, usi...
  function _ffi_vec_Bar_to_cpp (line 62) | fn _ffi_vec_Bar_to_cpp(items: Vec<Bar>, buf: &mut Vec<u8>) {
  function _ffi_vec_Foo_to_cpp (line 71) | fn _ffi_vec_Foo_to_cpp(items: Vec<Foo>, buf: &mut Vec<u8>) {
  function _ffi_vec__i32_f32_bool_to_cpp (line 84) | fn _ffi_vec__i32_f32_bool_to_cpp(items: Vec<((), (i32,), (f32, bool))>, ...
  function _ffi_write (line 93) | fn _ffi_write<T: Copy>(val: T, buf: &mut Vec<u8>) {

FILE: src/tests/snapshots/cpp_fn_combo_out_2024/ffi.cpp
  type _ffi_ret_i32_ptr_4_usize (line 5) | struct _ffi_ret_i32_ptr_4_usize {
  function T (line 26) | T _ffi_read(const uint8_t* &ptr) {
  function _ffi_vec__i32_f32_bool_from_rust (line 37) | std::vector<std::tuple<std::tuple<>, std::tuple<int32_t>, std::tuple<flo...
  function _ffi_vec_Foo_from_rust (line 53) | std::vector<rust::Foo> _ffi_vec_Foo_from_rust(uintptr_t len, const uint8...
  function _ffi_vec_Bar_from_rust (line 72) | std::vector<rust::Bar> _ffi_vec_Bar_from_rust(uintptr_t len, const uint8...

FILE: src/tests/snapshots/cpp_fn_combo_out_2024/ffi.h
  function namespace (line 9) | namespace rust {

FILE: src/tests/snapshots/cpp_fn_combo_out_2024/miniffi.rs
  function _ffi_dealloc (line 4) | extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) {
  function _ffi_buf_to_host (line 8) | fn _ffi_buf_to_host(buf: Vec<u8>) -> (*const u8, usize) {
  function _ffi_fn_check_combo1 (line 14) | extern "C" fn _ffi_fn_check_combo1() -> _ffi_ret_i32_ptr_4_usize {
  function _ffi_fn_check_combo2 (line 34) | extern "C" fn _ffi_fn_check_combo2() -> _ffi_ret_i32_ptr_4_usize {
  function _ffi_fn_rust_mem_leaked (line 54) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {
  type _ffi_ret_i32_ptr_4_usize (line 59) | struct _ffi_ret_i32_ptr_4_usize(i32, *const u8, usize, usize, usize, usi...
  function _ffi_vec_Bar_to_cpp (line 62) | fn _ffi_vec_Bar_to_cpp(items: Vec<Bar>, buf: &mut Vec<u8>) {
  function _ffi_vec_Foo_to_cpp (line 71) | fn _ffi_vec_Foo_to_cpp(items: Vec<Foo>, buf: &mut Vec<u8>) {
  function _ffi_vec__i32_f32_bool_to_cpp (line 84) | fn _ffi_vec__i32_f32_bool_to_cpp(items: Vec<((), (i32,), (f32, bool))>, ...
  function _ffi_write (line 93) | fn _ffi_write<T: Copy>(val: T, buf: &mut Vec<u8>) {

FILE: src/tests/snapshots/cpp_fn_enum_in_2021/ffi.cpp
  function _ffi_write (line 20) | void _ffi_write(T val, std::vector<uint8_t> &buf) {
  function _ffi_enum_LongEnum_to_rust (line 24) | void _ffi_enum_LongEnum_to_rust(rust::LongEnum val, std::vector<uint8_t>...

FILE: src/tests/snapshots/cpp_fn_enum_in_2021/ffi.h
  function namespace (line 8) | namespace rust {

FILE: src/tests/snapshots/cpp_fn_enum_in_2021/miniffi.rs
  function _ffi_alloc (line 4) | extern "C" fn _ffi_alloc(len: usize) -> *const u8 {
  function _ffi_buf_from_host (line 8) | fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) {
  function _ffi_enum_Big_from_cpp (line 14) | fn _ffi_enum_Big_from_cpp(val: i32) -> Big {
  function _ffi_enum_Foo_from_cpp (line 23) | fn _ffi_enum_Foo_from_cpp(val: i32) -> Foo {
  function _ffi_read (line 32) | fn _ffi_read<T: Copy>(ptr: &mut *const u8) -> T {
  function _ffi_enum_LongEnum_from_cpp (line 39) | fn _ffi_enum_LongEnum_from_cpp(end: &mut *const u8) -> LongEnum {
  function _ffi_fn_big_to_i32 (line 67) | extern "C" fn _ffi_fn_big_to_i32(big_raw: i32) -> i32 {
  function _ffi_fn_foo_to_i32 (line 72) | extern "C" fn _ffi_fn_foo_to_i32(foo_raw: i32) -> i32 {
  function _ffi_fn_long_in (line 77) | extern "C" fn _ffi_fn_long_in(buf_ptr: *const u8) {
  function _ffi_fn_rust_mem_leaked (line 84) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {

FILE: src/tests/snapshots/cpp_fn_enum_in_2024/ffi.cpp
  function _ffi_write (line 20) | void _ffi_write(T val, std::vector<uint8_t> &buf) {
  function _ffi_enum_LongEnum_to_rust (line 24) | void _ffi_enum_LongEnum_to_rust(rust::LongEnum val, std::vector<uint8_t>...

FILE: src/tests/snapshots/cpp_fn_enum_in_2024/ffi.h
  function namespace (line 8) | namespace rust {

FILE: src/tests/snapshots/cpp_fn_enum_in_2024/miniffi.rs
  function _ffi_alloc (line 4) | extern "C" fn _ffi_alloc(len: usize) -> *const u8 {
  function _ffi_buf_from_host (line 8) | fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) {
  function _ffi_enum_Big_from_cpp (line 14) | fn _ffi_enum_Big_from_cpp(val: i32) -> Big {
  function _ffi_enum_Foo_from_cpp (line 23) | fn _ffi_enum_Foo_from_cpp(val: i32) -> Foo {
  function _ffi_read (line 32) | fn _ffi_read<T: Copy>(ptr: &mut *const u8) -> T {
  function _ffi_enum_LongEnum_from_cpp (line 39) | fn _ffi_enum_LongEnum_from_cpp(end: &mut *const u8) -> LongEnum {
  function _ffi_fn_big_to_i32 (line 67) | extern "C" fn _ffi_fn_big_to_i32(big_raw: i32) -> i32 {
  function _ffi_fn_foo_to_i32 (line 72) | extern "C" fn _ffi_fn_foo_to_i32(foo_raw: i32) -> i32 {
  function _ffi_fn_long_in (line 77) | extern "C" fn _ffi_fn_long_in(buf_ptr: *const u8) {
  function _ffi_fn_rust_mem_leaked (line 84) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {

FILE: src/tests/snapshots/cpp_fn_enum_out_2021/ffi.cpp
  type _ffi_ret_ptr_usize (line 6) | struct _ffi_ret_ptr_usize {
  function T (line 24) | T _ffi_read(const uint8_t* &ptr) {
  function _ffi_enum_LongEnum_from_rust (line 31) | rust::LongEnum _ffi_enum_LongEnum_from_rust(const uint8_t*& end) {

FILE: src/tests/snapshots/cpp_fn_enum_out_2021/ffi.h
  function namespace (line 8) | namespace rust {

FILE: src/tests/snapshots/cpp_fn_enum_out_2021/miniffi.rs
  function _ffi_dealloc (line 4) | extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) {
  function _ffi_buf_to_host (line 8) | fn _ffi_buf_to_host(buf: Vec<u8>) -> (*const u8, usize) {
  function _ffi_write (line 13) | fn _ffi_write<T: Copy>(val: T, buf: &mut Vec<u8>) {
  function _ffi_enum_LongEnum_to_cpp (line 20) | fn _ffi_enum_LongEnum_to_cpp(val: LongEnum, buf: &mut Vec<u8>) {
  function _ffi_fn_i32_to_big (line 55) | extern "C" fn _ffi_fn_i32_to_big(big: i32) -> i32 {
  function _ffi_fn_i32_to_foo (line 60) | extern "C" fn _ffi_fn_i32_to_foo(foo: i32) -> i32 {
  function _ffi_fn_long_out (line 65) | extern "C" fn _ffi_fn_long_out() -> _ffi_ret_ptr_usize {
  function _ffi_fn_rust_mem_leaked (line 73) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {
  type _ffi_ret_ptr_usize (line 78) | struct _ffi_ret_ptr_usize(*const u8, usize);

FILE: src/tests/snapshots/cpp_fn_enum_out_2024/ffi.cpp
  type _ffi_ret_ptr_usize (line 6) | struct _ffi_ret_ptr_usize {
  function T (line 24) | T _ffi_read(const uint8_t* &ptr) {
  function _ffi_enum_LongEnum_from_rust (line 31) | rust::LongEnum _ffi_enum_LongEnum_from_rust(const uint8_t*& end) {

FILE: src/tests/snapshots/cpp_fn_enum_out_2024/ffi.h
  function namespace (line 8) | namespace rust {

FILE: src/tests/snapshots/cpp_fn_enum_out_2024/miniffi.rs
  function _ffi_dealloc (line 4) | extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) {
  function _ffi_buf_to_host (line 8) | fn _ffi_buf_to_host(buf: Vec<u8>) -> (*const u8, usize) {
  function _ffi_write (line 13) | fn _ffi_write<T: Copy>(val: T, buf: &mut Vec<u8>) {
  function _ffi_enum_LongEnum_to_cpp (line 20) | fn _ffi_enum_LongEnum_to_cpp(val: LongEnum, buf: &mut Vec<u8>) {
  function _ffi_fn_i32_to_big (line 55) | extern "C" fn _ffi_fn_i32_to_big(big: i32) -> i32 {
  function _ffi_fn_i32_to_foo (line 60) | extern "C" fn _ffi_fn_i32_to_foo(foo: i32) -> i32 {
  function _ffi_fn_long_out (line 65) | extern "C" fn _ffi_fn_long_out() -> _ffi_ret_ptr_usize {
  function _ffi_fn_rust_mem_leaked (line 73) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {
  type _ffi_ret_ptr_usize (line 78) | struct _ffi_ret_ptr_usize(*const u8, usize);

FILE: src/tests/snapshots/cpp_fn_nested_in_2021/ffi.cpp
  function _ffi_write (line 16) | void _ffi_write(T val, std::vector<uint8_t> &buf) {
  function _ffi_vec_i32_Foo_to_rust (line 20) | void _ffi_vec_i32_Foo_to_rust(std::vector<std::tuple<int32_t, rust::Foo>...
  function _ffi_cpp_Rc_Bar__get (line 37) | int32_t _ffi_cpp_Rc_Bar__get(std::shared_ptr<rust::Bar>* _self) {
  function _ffi_cpp_drop_Rc_Bar (line 41) | void _ffi_cpp_drop_Rc_Bar(std::shared_ptr<rust::Bar>* self) {

FILE: src/tests/snapshots/cpp_fn_nested_in_2021/ffi.h
  function namespace (line 10) | namespace rust {

FILE: src/tests/snapshots/cpp_fn_nested_in_2021/miniffi.rs
  function _ffi_alloc (line 4) | extern "C" fn _ffi_alloc(len: usize) -> *const u8 {
  function _ffi_buf_from_host (line 8) | fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) {
  function _ffi_fn_rust_mem_leaked (line 14) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {
  function _ffi_fn_test (line 19) | extern "C" fn _ffi_fn_test(x_0: i32, x_1_ptr_ptr: *const u8, buf_ptr: *c...
  function _ffi_read (line 27) | fn _ffi_read<T: Copy>(ptr: &mut *const u8) -> T {
  type _ffi_rs_Rc_Bar (line 34) | struct _ffi_rs_Rc_Bar(*const u8);
  method drop (line 37) | fn drop(&mut self) {
  method get (line 44) | fn get(&self) -> i32 {
  function _ffi_vec_i32_Foo_from_cpp (line 51) | fn _ffi_vec_i32_Foo_from_cpp(len: usize, end: &mut *const u8) -> Vec<(i3...

FILE: src/tests/snapshots/cpp_fn_nested_in_2024/ffi.cpp
  function _ffi_write (line 16) | void _ffi_write(T val, std::vector<uint8_t> &buf) {
  function _ffi_vec_i32_Foo_to_rust (line 20) | void _ffi_vec_i32_Foo_to_rust(std::vector<std::tuple<int32_t, rust::Foo>...
  function _ffi_cpp_Rc_Bar__get (line 37) | int32_t _ffi_cpp_Rc_Bar__get(std::shared_ptr<rust::Bar>* _self) {
  function _ffi_cpp_drop_Rc_Bar (line 41) | void _ffi_cpp_drop_Rc_Bar(std::shared_ptr<rust::Bar>* self) {

FILE: src/tests/snapshots/cpp_fn_nested_in_2024/ffi.h
  function namespace (line 10) | namespace rust {

FILE: src/tests/snapshots/cpp_fn_nested_in_2024/miniffi.rs
  function _ffi_alloc (line 4) | extern "C" fn _ffi_alloc(len: usize) -> *const u8 {
  function _ffi_buf_from_host (line 8) | fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) {
  function _ffi_fn_rust_mem_leaked (line 14) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {
  function _ffi_fn_test (line 19) | extern "C" fn _ffi_fn_test(x_0: i32, x_1_ptr_ptr: *const u8, buf_ptr: *c...
  function _ffi_read (line 27) | fn _ffi_read<T: Copy>(ptr: &mut *const u8) -> T {
  type _ffi_rs_Rc_Bar (line 34) | struct _ffi_rs_Rc_Bar(*const u8);
  method drop (line 37) | fn drop(&mut self) {
  method get (line 44) | fn get(&self) -> i32 {
  function _ffi_vec_i32_Foo_from_cpp (line 51) | fn _ffi_vec_i32_Foo_from_cpp(len: usize, end: &mut *const u8) -> Vec<(i3...

FILE: src/tests/snapshots/cpp_fn_nested_out_2021/ffi.cpp
  type _ffi_ret_i32_ptr (line 5) | struct _ffi_ret_i32_ptr {
  type _ffi_Rc_Bar (line 21) | struct _ffi_Rc_Bar final : rust::Bar {
    method _ffi_Rc_Bar (line 22) | _ffi_Rc_Bar(const void* ptr) : _self(ptr) {}

FILE: src/tests/snapshots/cpp_fn_nested_out_2021/ffi.h
  function namespace (line 9) | namespace rust {

FILE: src/tests/snapshots/cpp_fn_nested_out_2021/miniffi.rs
  function _ffi_Rc_Bar__get (line 4) | extern "C" fn _ffi_Rc_Bar__get(_self: *const u8) -> i32 {
  function _ffi_drop_Rc_Bar (line 10) | extern "C" fn _ffi_drop_Rc_Bar(ptr: *const u8) {
  function _ffi_fn_rust_mem_leaked (line 15) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {
  function _ffi_fn_test (line 20) | extern "C" fn _ffi_fn_test(x: i32) -> _ffi_ret_i32_ptr {
  type _ffi_ret_i32_ptr (line 28) | struct _ffi_ret_i32_ptr(i32, *const u8);

FILE: src/tests/snapshots/cpp_fn_nested_out_2024/ffi.cpp
  type _ffi_ret_i32_ptr (line 5) | struct _ffi_ret_i32_ptr {
  type _ffi_Rc_Bar (line 21) | struct _ffi_Rc_Bar final : rust::Bar {
    method _ffi_Rc_Bar (line 22) | _ffi_Rc_Bar(const void* ptr) : _self(ptr) {}

FILE: src/tests/snapshots/cpp_fn_nested_out_2024/ffi.h
  function namespace (line 9) | namespace rust {

FILE: src/tests/snapshots/cpp_fn_nested_out_2024/miniffi.rs
  function _ffi_Rc_Bar__get (line 4) | extern "C" fn _ffi_Rc_Bar__get(_self: *const u8) -> i32 {
  function _ffi_drop_Rc_Bar (line 10) | extern "C" fn _ffi_drop_Rc_Bar(ptr: *const u8) {
  function _ffi_fn_rust_mem_leaked (line 15) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {
  function _ffi_fn_test (line 20) | extern "C" fn _ffi_fn_test(x: i32) -> _ffi_ret_i32_ptr {
  type _ffi_ret_i32_ptr (line 28) | struct _ffi_ret_i32_ptr(i32, *const u8);

FILE: src/tests/snapshots/cpp_fn_option_in_2021/ffi.cpp
  type _ffi_ret_ptr_2_usize (line 5) | struct _ffi_ret_ptr_2_usize {
  function _ffi_write (line 31) | void _ffi_write(T val, std::vector<uint8_t> &buf) {
  function _ffi_vec_option_i32_to_rust (line 35) | void _ffi_vec_option_i32_to_rust(std::vector<std::optional<int32_t>>&& i...
  function _ffi_string_from_rust (line 49) | std::string _ffi_string_from_rust(const char* ptr, uintptr_t len, uintpt...
  function _ffi_vec_option_string_to_rust (line 55) | void _ffi_vec_option_string_to_rust(std::vector<std::optional<std::strin...

FILE: src/tests/snapshots/cpp_fn_option_in_2021/ffi.h
  function namespace (line 10) | namespace rust {

FILE: src/tests/snapshots/cpp_fn_option_in_2021/miniffi.rs
  function _ffi_alloc (line 4) | extern "C" fn _ffi_alloc(len: usize) -> *const u8 {
  function _ffi_buf_from_host (line 8) | fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) {
  function _ffi_fn_add_all (line 14) | extern "C" fn _ffi_fn_add_all(buf_ptr: *const u8, x_len: usize) -> i32 {
  function _ffi_fn_add_nested (line 22) | extern "C" fn _ffi_fn_add_nested(buf_ptr: *const u8, has_x: bool, has_y:...
  function _ffi_fn_add_option (line 33) | extern "C" fn _ffi_fn_add_option(buf_ptr: *const u8, has_x: bool, has_y:...
  function _ffi_fn_join_all (line 41) | extern "C" fn _ffi_fn_join_all(buf_ptr: *const u8, x_len: usize) -> _ffi...
  function _ffi_fn_rust_mem_leaked (line 49) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {
  function _ffi_read (line 53) | fn _ffi_read<T: Copy>(ptr: &mut *const u8) -> T {
  type _ffi_ret_ptr_2_usize (line 60) | struct _ffi_ret_ptr_2_usize(*const u8, usize, usize);
  function _ffi_string_from_host (line 62) | fn _ffi_string_from_host(ptr: *const u8, len: usize) -> String {
  function _ffi_dealloc (line 67) | extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) {
  function _ffi_string_to_host (line 71) | fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) {
  function _ffi_vec_option_i32_from_cpp (line 76) | fn _ffi_vec_option_i32_from_cpp(len: usize, end: &mut *const u8) -> Vec<...
  function _ffi_vec_option_string_from_cpp (line 84) | fn _ffi_vec_option_string_from_cpp(len: usize, end: &mut *const u8) -> V...

FILE: src/tests/snapshots/cpp_fn_option_in_2024/ffi.cpp
  type _ffi_ret_ptr_2_usize (line 5) | struct _ffi_ret_ptr_2_usize {
  function _ffi_write (line 31) | void _ffi_write(T val, std::vector<uint8_t> &buf) {
  function _ffi_vec_option_i32_to_rust (line 35) | void _ffi_vec_option_i32_to_rust(std::vector<std::optional<int32_t>>&& i...
  function _ffi_string_from_rust (line 49) | std::string _ffi_string_from_rust(const char* ptr, uintptr_t len, uintpt...
  function _ffi_vec_option_string_to_rust (line 55) | void _ffi_vec_option_string_to_rust(std::vector<std::optional<std::strin...

FILE: src/tests/snapshots/cpp_fn_option_in_2024/ffi.h
  function namespace (line 10) | namespace rust {

FILE: src/tests/snapshots/cpp_fn_option_in_2024/miniffi.rs
  function _ffi_alloc (line 4) | extern "C" fn _ffi_alloc(len: usize) -> *const u8 {
  function _ffi_buf_from_host (line 8) | fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) {
  function _ffi_fn_add_all (line 14) | extern "C" fn _ffi_fn_add_all(buf_ptr: *const u8, x_len: usize) -> i32 {
  function _ffi_fn_add_nested (line 22) | extern "C" fn _ffi_fn_add_nested(buf_ptr: *const u8, has_x: bool, has_y:...
  function _ffi_fn_add_option (line 33) | extern "C" fn _ffi_fn_add_option(buf_ptr: *const u8, has_x: bool, has_y:...
  function _ffi_fn_join_all (line 41) | extern "C" fn _ffi_fn_join_all(buf_ptr: *const u8, x_len: usize) -> _ffi...
  function _ffi_fn_rust_mem_leaked (line 49) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {
  function _ffi_read (line 53) | fn _ffi_read<T: Copy>(ptr: &mut *const u8) -> T {
  type _ffi_ret_ptr_2_usize (line 60) | struct _ffi_ret_ptr_2_usize(*const u8, usize, usize);
  function _ffi_string_from_host (line 62) | fn _ffi_string_from_host(ptr: *const u8, len: usize) -> String {
  function _ffi_dealloc (line 67) | extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) {
  function _ffi_string_to_host (line 71) | fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) {
  function _ffi_vec_option_i32_from_cpp (line 76) | fn _ffi_vec_option_i32_from_cpp(len: usize, end: &mut *const u8) -> Vec<...
  function _ffi_vec_option_string_from_cpp (line 84) | fn _ffi_vec_option_string_from_cpp(len: usize, end: &mut *const u8) -> V...

FILE: src/tests/snapshots/cpp_fn_option_out_2021/ffi.cpp
  type _ffi_ret_ptr_2_usize (line 5) | struct _ffi_ret_ptr_2_usize {
  type _ffi_ret_ptr_usize_bool (line 11) | struct _ffi_ret_ptr_usize_bool {
  function T (line 31) | T _ffi_read(const uint8_t* &ptr) {
  function _ffi_string_from_rust (line 38) | std::string _ffi_string_from_rust(const char* ptr, uintptr_t len, uintpt...
  function _ffi_vec_option_string_from_rust (line 44) | std::vector<std::optional<std::string>> _ffi_vec_option_string_from_rust...
  function _ffi_vec_option_i32_from_rust (line 60) | std::vector<std::optional<int32_t>> _ffi_vec_option_i32_from_rust(uintpt...

FILE: src/tests/snapshots/cpp_fn_option_out_2021/ffi.h
  function namespace (line 10) | namespace rust {

FILE: src/tests/snapshots/cpp_fn_option_out_2021/miniffi.rs
  function _ffi_dealloc (line 4) | extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) {
  function _ffi_buf_to_host (line 8) | fn _ffi_buf_to_host(buf: Vec<u8>) -> (*const u8, usize) {
  function _ffi_fn_opt_int (line 14) | extern "C" fn _ffi_fn_opt_int(x: bool, y: i32) -> _ffi_ret_ptr_usize_bool {
  function _ffi_fn_opt_opt_int (line 26) | extern "C" fn _ffi_fn_opt_opt_int(x: bool, y: bool, z: i32) -> _ffi_ret_...
  function _ffi_fn_opt_vec_opt_string (line 41) | extern "C" fn _ffi_fn_opt_vec_opt_string(n: i32) -> _ffi_ret_ptr_usize_b...
  function _ffi_fn_rust_mem_leaked (line 54) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {
  function _ffi_fn_vec_opt_int (line 59) | extern "C" fn _ffi_fn_vec_opt_int(n: i32) -> _ffi_ret_ptr_2_usize {
  type _ffi_ret_ptr_2_usize (line 69) | struct _ffi_ret_ptr_2_usize(*const u8, usize, usize);
  type _ffi_ret_ptr_usize_bool (line 72) | struct _ffi_ret_ptr_usize_bool(*const u8, usize, bool);
  function _ffi_string_to_host (line 74) | fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) {
  function _ffi_vec_option_i32_to_cpp (line 79) | fn _ffi_vec_option_i32_to_cpp(items: Vec<Option<i32>>, buf: &mut Vec<u8>) {
  function _ffi_vec_option_string_to_cpp (line 88) | fn _ffi_vec_option_string_to_cpp(items: Vec<Option<String>>, buf: &mut V...
  function _ffi_write (line 100) | fn _ffi_write<T: Copy>(val: T, buf: &mut Vec<u8>) {

FILE: src/tests/snapshots/cpp_fn_option_out_2024/ffi.cpp
  type _ffi_ret_ptr_2_usize (line 5) | struct _ffi_ret_ptr_2_usize {
  type _ffi_ret_ptr_usize_bool (line 11) | struct _ffi_ret_ptr_usize_bool {
  function T (line 31) | T _ffi_read(const uint8_t* &ptr) {
  function _ffi_string_from_rust (line 38) | std::string _ffi_string_from_rust(const char* ptr, uintptr_t len, uintpt...
  function _ffi_vec_option_string_from_rust (line 44) | std::vector<std::optional<std::string>> _ffi_vec_option_string_from_rust...
  function _ffi_vec_option_i32_from_rust (line 60) | std::vector<std::optional<int32_t>> _ffi_vec_option_i32_from_rust(uintpt...

FILE: src/tests/snapshots/cpp_fn_option_out_2024/ffi.h
  function namespace (line 10) | namespace rust {

FILE: src/tests/snapshots/cpp_fn_option_out_2024/miniffi.rs
  function _ffi_dealloc (line 4) | extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) {
  function _ffi_buf_to_host (line 8) | fn _ffi_buf_to_host(buf: Vec<u8>) -> (*const u8, usize) {
  function _ffi_fn_opt_int (line 14) | extern "C" fn _ffi_fn_opt_int(x: bool, y: i32) -> _ffi_ret_ptr_usize_bool {
  function _ffi_fn_opt_opt_int (line 26) | extern "C" fn _ffi_fn_opt_opt_int(x: bool, y: bool, z: i32) -> _ffi_ret_...
  function _ffi_fn_opt_vec_opt_string (line 41) | extern "C" fn _ffi_fn_opt_vec_opt_string(n: i32) -> _ffi_ret_ptr_usize_b...
  function _ffi_fn_rust_mem_leaked (line 54) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {
  function _ffi_fn_vec_opt_int (line 59) | extern "C" fn _ffi_fn_vec_opt_int(n: i32) -> _ffi_ret_ptr_2_usize {
  type _ffi_ret_ptr_2_usize (line 69) | struct _ffi_ret_ptr_2_usize(*const u8, usize, usize);
  type _ffi_ret_ptr_usize_bool (line 72) | struct _ffi_ret_ptr_usize_bool(*const u8, usize, bool);
  function _ffi_string_to_host (line 74) | fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) {
  function _ffi_vec_option_i32_to_cpp (line 79) | fn _ffi_vec_option_i32_to_cpp(items: Vec<Option<i32>>, buf: &mut Vec<u8>) {
  function _ffi_vec_option_string_to_cpp (line 88) | fn _ffi_vec_option_string_to_cpp(items: Vec<Option<String>>, buf: &mut V...
  function _ffi_write (line 100) | fn _ffi_write<T: Copy>(val: T, buf: &mut Vec<u8>) {

FILE: src/tests/snapshots/cpp_fn_payload_in_2021/ffi.cpp
  function _ffi_box_Foo_to_rust (line 18) | void _ffi_box_Foo_to_rust(rust::Foo val, std::vector<uint8_t>& buf) {
  function _ffi_write (line 23) | void _ffi_write(T val, std::vector<uint8_t> &buf) {
  function _ffi_enum_Foo_to_rust (line 27) | void _ffi_enum_Foo_to_rust(rust::Foo val, std::vector<uint8_t>& buf) {
  function _ffi_vec_Foo_to_rust (line 45) | void _ffi_vec_Foo_to_rust(std::vector<rust::Foo>&& items, std::vector<ui...

FILE: src/tests/snapshots/cpp_fn_payload_in_2021/ffi.h
  function namespace (line 10) | namespace rust {
  type Foo (line 42) | struct Foo

FILE: src/tests/snapshots/cpp_fn_payload_in_2021/miniffi.rs
  function _ffi_box_Foo_from_cpp (line 4) | fn _ffi_box_Foo_from_cpp(end: &mut *const u8) -> Box<Foo> {
  function _ffi_alloc (line 9) | extern "C" fn _ffi_alloc(len: usize) -> *const u8 {
  function _ffi_buf_from_host (line 13) | fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) {
  function _ffi_read (line 18) | fn _ffi_read<T: Copy>(ptr: &mut *const u8) -> T {
  function _ffi_enum_Foo_from_cpp (line 25) | fn _ffi_enum_Foo_from_cpp(end: &mut *const u8) -> Foo {
  function _ffi_fn_rust_mem_leaked (line 36) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {
  function _ffi_fn_set_tests (line 41) | extern "C" fn _ffi_fn_set_tests(buf_ptr: *const u8, tests_len: usize) ->...
  function _ffi_vec_Foo_from_cpp (line 49) | fn _ffi_vec_Foo_from_cpp(len: usize, end: &mut *const u8) -> Vec<Foo> {

FILE: src/tests/snapshots/cpp_fn_payload_in_2024/ffi.cpp
  function _ffi_box_Foo_to_rust (line 18) | void _ffi_box_Foo_to_rust(rust::Foo val, std::vector<uint8_t>& buf) {
  function _ffi_write (line 23) | void _ffi_write(T val, std::vector<uint8_t> &buf) {
  function _ffi_enum_Foo_to_rust (line 27) | void _ffi_enum_Foo_to_rust(rust::Foo val, std::vector<uint8_t>& buf) {
  function _ffi_vec_Foo_to_rust (line 45) | void _ffi_vec_Foo_to_rust(std::vector<rust::Foo>&& items, std::vector<ui...

FILE: src/tests/snapshots/cpp_fn_payload_in_2024/ffi.h
  function namespace (line 10) | namespace rust {
  type Foo (line 42) | struct Foo

FILE: src/tests/snapshots/cpp_fn_payload_in_2024/miniffi.rs
  function _ffi_box_Foo_from_cpp (line 4) | fn _ffi_box_Foo_from_cpp(end: &mut *const u8) -> Box<Foo> {
  function _ffi_alloc (line 9) | extern "C" fn _ffi_alloc(len: usize) -> *const u8 {
  function _ffi_buf_from_host (line 13) | fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) {
  function _ffi_read (line 18) | fn _ffi_read<T: Copy>(ptr: &mut *const u8) -> T {
  function _ffi_enum_Foo_from_cpp (line 25) | fn _ffi_enum_Foo_from_cpp(end: &mut *const u8) -> Foo {
  function _ffi_fn_rust_mem_leaked (line 36) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {
  function _ffi_fn_set_tests (line 41) | extern "C" fn _ffi_fn_set_tests(buf_ptr: *const u8, tests_len: usize) ->...
  function _ffi_vec_Foo_from_cpp (line 49) | fn _ffi_vec_Foo_from_cpp(len: usize, end: &mut *const u8) -> Vec<Foo> {

FILE: src/tests/snapshots/cpp_fn_payload_out_2021/ffi.cpp
  type _ffi_ret_ptr_2_usize (line 6) | struct _ffi_ret_ptr_2_usize {
  function _ffi_box_Foo_from_rust (line 24) | std::unique_ptr<rust::Foo> _ffi_box_Foo_from_rust(const uint8_t*& end) {
  function T (line 30) | T _ffi_read(const uint8_t* &ptr) {
  function _ffi_enum_Foo_from_rust (line 37) | rust::Foo _ffi_enum_Foo_from_rust(const uint8_t*& end) {
  function _ffi_vec_Foo_from_rust (line 59) | std::vector<rust::Foo> _ffi_vec_Foo_from_rust(uintptr_t len, const uint8...

FILE: src/tests/snapshots/cpp_fn_payload_out_2021/ffi.h
  function namespace (line 10) | namespace rust {
  type Foo (line 42) | struct Foo

FILE: src/tests/snapshots/cpp_fn_payload_out_2021/miniffi.rs
  function _ffi_box_Foo_to_cpp (line 4) | fn _ffi_box_Foo_to_cpp(val: Foo, buf: &mut Vec<u8>) {
  function _ffi_dealloc (line 9) | extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) {
  function _ffi_buf_to_host (line 13) | fn _ffi_buf_to_host(buf: Vec<u8>) -> (*const u8, usize) {
  function _ffi_write (line 18) | fn _ffi_write<T: Copy>(val: T, buf: &mut Vec<u8>) {
  function _ffi_enum_Foo_to_cpp (line 25) | fn _ffi_enum_Foo_to_cpp(val: Foo, buf: &mut Vec<u8>) {
  function _ffi_fn_get_tests (line 45) | extern "C" fn _ffi_fn_get_tests() -> _ffi_ret_ptr_2_usize {
  function _ffi_fn_rust_mem_leaked (line 55) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {
  type _ffi_ret_ptr_2_usize (line 60) | struct _ffi_ret_ptr_2_usize(*const u8, usize, usize);
  function _ffi_vec_Foo_to_cpp (line 63) | fn _ffi_vec_Foo_to_cpp(items: Vec<Foo>, buf: &mut Vec<u8>) {

FILE: src/tests/snapshots/cpp_fn_payload_out_2024/ffi.cpp
  type _ffi_ret_ptr_2_usize (line 6) | struct _ffi_ret_ptr_2_usize {
  function _ffi_box_Foo_from_rust (line 24) | std::unique_ptr<rust::Foo> _ffi_box_Foo_from_rust(const uint8_t*& end) {
  function T (line 30) | T _ffi_read(const uint8_t* &ptr) {
  function _ffi_enum_Foo_from_rust (line 37) | rust::Foo _ffi_enum_Foo_from_rust(const uint8_t*& end) {
  function _ffi_vec_Foo_from_rust (line 59) | std::vector<rust::Foo> _ffi_vec_Foo_from_rust(uintptr_t len, const uint8...

FILE: src/tests/snapshots/cpp_fn_payload_out_2024/ffi.h
  function namespace (line 10) | namespace rust {
  type Foo (line 42) | struct Foo

FILE: src/tests/snapshots/cpp_fn_payload_out_2024/miniffi.rs
  function _ffi_box_Foo_to_cpp (line 4) | fn _ffi_box_Foo_to_cpp(val: Foo, buf: &mut Vec<u8>) {
  function _ffi_dealloc (line 9) | extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) {
  function _ffi_buf_to_host (line 13) | fn _ffi_buf_to_host(buf: Vec<u8>) -> (*const u8, usize) {
  function _ffi_write (line 18) | fn _ffi_write<T: Copy>(val: T, buf: &mut Vec<u8>) {
  function _ffi_enum_Foo_to_cpp (line 25) | fn _ffi_enum_Foo_to_cpp(val: Foo, buf: &mut Vec<u8>) {
  function _ffi_fn_get_tests (line 45) | extern "C" fn _ffi_fn_get_tests() -> _ffi_ret_ptr_2_usize {
  function _ffi_fn_rust_mem_leaked (line 55) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {
  type _ffi_ret_ptr_2_usize (line 60) | struct _ffi_ret_ptr_2_usize(*const u8, usize, usize);
  function _ffi_vec_Foo_to_cpp (line 63) | fn _ffi_vec_Foo_to_cpp(items: Vec<Foo>, buf: &mut Vec<u8>) {

FILE: src/tests/snapshots/cpp_fn_string_2021/ffi.cpp
  type _ffi_ret_ptr_2_usize (line 5) | struct _ffi_ret_ptr_2_usize {
  function _ffi_string_from_rust (line 31) | std::string _ffi_string_from_rust(const char* ptr, uintptr_t len, uintpt...

FILE: src/tests/snapshots/cpp_fn_string_2021/ffi.h
  function namespace (line 8) | namespace rust {

FILE: src/tests/snapshots/cpp_fn_string_2021/miniffi.rs
  function _ffi_fn_get_string (line 4) | extern "C" fn _ffi_fn_get_string() -> _ffi_ret_ptr_2_usize {
  function _ffi_fn_get_string_len (line 10) | extern "C" fn _ffi_fn_get_string_len() -> i32 {
  function _ffi_fn_reset (line 15) | extern "C" fn _ffi_fn_reset() {
  function _ffi_fn_rust_mem_leaked (line 20) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {
  function _ffi_fn_set_str (line 25) | extern "C" fn _ffi_fn_set_str(x_ptr: *const u8, x_len: usize) {
  function _ffi_fn_set_string (line 30) | extern "C" fn _ffi_fn_set_string(x_ptr: *const u8, x_len: usize) {
  type _ffi_ret_ptr_2_usize (line 35) | struct _ffi_ret_ptr_2_usize(*const u8, usize, usize);
  function _ffi_alloc (line 38) | extern "C" fn _ffi_alloc(len: usize) -> *const u8 {
  function _ffi_string_from_host (line 42) | fn _ffi_string_from_host(ptr: *const u8, len: usize) -> String {
  function _ffi_dealloc (line 47) | extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) {
  function _ffi_string_to_host (line 51) | fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) {

FILE: src/tests/snapshots/cpp_fn_string_2024/ffi.cpp
  type _ffi_ret_ptr_2_usize (line 5) | struct _ffi_ret_ptr_2_usize {
  function _ffi_string_from_rust (line 31) | std::string _ffi_string_from_rust(const char* ptr, uintptr_t len, uintpt...

FILE: src/tests/snapshots/cpp_fn_string_2024/ffi.h
  function namespace (line 8) | namespace rust {

FILE: src/tests/snapshots/cpp_fn_string_2024/miniffi.rs
  function _ffi_fn_get_string (line 4) | extern "C" fn _ffi_fn_get_string() -> _ffi_ret_ptr_2_usize {
  function _ffi_fn_get_string_len (line 10) | extern "C" fn _ffi_fn_get_string_len() -> i32 {
  function _ffi_fn_reset (line 15) | extern "C" fn _ffi_fn_reset() {
  function _ffi_fn_rust_mem_leaked (line 20) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {
  function _ffi_fn_set_str (line 25) | extern "C" fn _ffi_fn_set_str(x_ptr: *const u8, x_len: usize) {
  function _ffi_fn_set_string (line 30) | extern "C" fn _ffi_fn_set_string(x_ptr: *const u8, x_len: usize) {
  type _ffi_ret_ptr_2_usize (line 35) | struct _ffi_ret_ptr_2_usize(*const u8, usize, usize);
  function _ffi_alloc (line 38) | extern "C" fn _ffi_alloc(len: usize) -> *const u8 {
  function _ffi_string_from_host (line 42) | fn _ffi_string_from_host(ptr: *const u8, len: usize) -> String {
  function _ffi_dealloc (line 47) | extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) {
  function _ffi_string_to_host (line 51) | fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) {

FILE: src/tests/snapshots/cpp_fn_struct_in_2021/ffi.h
  function namespace (line 7) | namespace rust {

FILE: src/tests/snapshots/cpp_fn_struct_in_2021/miniffi.rs
  function _ffi_fn_empty_tuple (line 4) | extern "C" fn _ffi_fn_empty_tuple(x: i32, y: i32) -> i32 {
  function _ffi_fn_multiply_pairs (line 9) | extern "C" fn _ffi_fn_multiply_pairs(ab_x: f32, ab_y: f32, cd_x: f32, cd...
  function _ffi_fn_rust_mem_leaked (line 14) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {
  function _ffi_fn_single_element_tuple (line 19) | extern "C" fn _ffi_fn_single_element_tuple(x_0: i32, y_0: i32) -> i32 {

FILE: src/tests/snapshots/cpp_fn_struct_in_2024/ffi.h
  function namespace (line 7) | namespace rust {

FILE: src/tests/snapshots/cpp_fn_struct_in_2024/miniffi.rs
  function _ffi_fn_empty_tuple (line 4) | extern "C" fn _ffi_fn_empty_tuple(x: i32, y: i32) -> i32 {
  function _ffi_fn_multiply_pairs (line 9) | extern "C" fn _ffi_fn_multiply_pairs(ab_x: f32, ab_y: f32, cd_x: f32, cd...
  function _ffi_fn_rust_mem_leaked (line 14) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {
  function _ffi_fn_single_element_tuple (line 19) | extern "C" fn _ffi_fn_single_element_tuple(x_0: i32, y_0: i32) -> i32 {

FILE: src/tests/snapshots/cpp_fn_struct_out_2021/ffi.cpp
  type _ffi_ret_2_f32 (line 5) | struct _ffi_ret_2_f32 {

FILE: src/tests/snapshots/cpp_fn_struct_out_2021/ffi.h
  function namespace (line 7) | namespace rust {
  type PairStruct (line 14) | struct PairStruct {
  type SingleElementStruct (line 21) | struct SingleElementStruct {

FILE: src/tests/snapshots/cpp_fn_struct_out_2021/miniffi.rs
  function _ffi_fn_empty_struct (line 4) | extern "C" fn _ffi_fn_empty_struct() {
  function _ffi_fn_make_pair (line 9) | extern "C" fn _ffi_fn_make_pair(x: f32, y: f32) -> _ffi_ret_2_f32 {
  function _ffi_fn_rust_mem_leaked (line 15) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {
  function _ffi_fn_single_element_struct (line 20) | extern "C" fn _ffi_fn_single_element_struct(x: i32) -> i32 {
  type _ffi_ret_2_f32 (line 26) | struct _ffi_ret_2_f32(f32, f32);

FILE: src/tests/snapshots/cpp_fn_struct_out_2024/ffi.cpp
  type _ffi_ret_2_f32 (line 5) | struct _ffi_ret_2_f32 {

FILE: src/tests/snapshots/cpp_fn_struct_out_2024/ffi.h
  function namespace (line 7) | namespace rust {
  type PairStruct (line 14) | struct PairStruct {
  type SingleElementStruct (line 21) | struct SingleElementStruct {

FILE: src/tests/snapshots/cpp_fn_struct_out_2024/miniffi.rs
  function _ffi_fn_empty_struct (line 4) | extern "C" fn _ffi_fn_empty_struct() {
  function _ffi_fn_make_pair (line 9) | extern "C" fn _ffi_fn_make_pair(x: f32, y: f32) -> _ffi_ret_2_f32 {
  function _ffi_fn_rust_mem_leaked (line 15) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {
  function _ffi_fn_single_element_struct (line 20) | extern "C" fn _ffi_fn_single_element_struct(x: i32) -> i32 {
  type _ffi_ret_2_f32 (line 26) | struct _ffi_ret_2_f32(f32, f32);

FILE: src/tests/snapshots/cpp_fn_tuple_in_2021/ffi.h
  function namespace (line 8) | namespace rust {

FILE: src/tests/snapshots/cpp_fn_tuple_in_2021/miniffi.rs
  function _ffi_fn_empty_tuple (line 4) | extern "C" fn _ffi_fn_empty_tuple(x: i32, y: i32) -> i32 {
  function _ffi_fn_multiply_pairs (line 9) | extern "C" fn _ffi_fn_multiply_pairs(ab_0: f32, ab_1: f32, cd_0: f32, cd...
  function _ffi_fn_nesting (line 14) | extern "C" fn _ffi_fn_nesting(x_0: i32, x_2_0: i32, x_2_1_0: i32) -> i32 {
  function _ffi_fn_rust_mem_leaked (line 19) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {
  function _ffi_fn_single_element_tuple (line 24) | extern "C" fn _ffi_fn_single_element_tuple(x_0: i32, y_0: i32) -> i32 {

FILE: src/tests/snapshots/cpp_fn_tuple_in_2024/ffi.h
  function namespace (line 8) | namespace rust {

FILE: src/tests/snapshots/cpp_fn_tuple_in_2024/miniffi.rs
  function _ffi_fn_empty_tuple (line 4) | extern "C" fn _ffi_fn_empty_tuple(x: i32, y: i32) -> i32 {
  function _ffi_fn_multiply_pairs (line 9) | extern "C" fn _ffi_fn_multiply_pairs(ab_0: f32, ab_1: f32, cd_0: f32, cd...
  function _ffi_fn_nesting (line 14) | extern "C" fn _ffi_fn_nesting(x_0: i32, x_2_0: i32, x_2_1_0: i32) -> i32 {
  function _ffi_fn_rust_mem_leaked (line 19) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {
  function _ffi_fn_single_element_tuple (line 24) | extern "C" fn _ffi_fn_single_element_tuple(x_0: i32, y_0: i32) -> i32 {

FILE: src/tests/snapshots/cpp_fn_tuple_out_2021/ffi.cpp
  type _ffi_ret_f32_bool (line 5) | struct _ffi_ret_f32_bool {

FILE: src/tests/snapshots/cpp_fn_tuple_out_2021/ffi.h
  function namespace (line 8) | namespace rust {

FILE: src/tests/snapshots/cpp_fn_tuple_out_2021/miniffi.rs
  function _ffi_fn_return_pair (line 4) | extern "C" fn _ffi_fn_return_pair(x: f32, y: bool) -> _ffi_ret_f32_bool {
  function _ffi_fn_rust_mem_leaked (line 10) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {
  function _ffi_fn_single_element_tuple (line 15) | extern "C" fn _ffi_fn_single_element_tuple(x: i32) -> i32 {
  type _ffi_ret_f32_bool (line 21) | struct _ffi_ret_f32_bool(f32, bool);

FILE: src/tests/snapshots/cpp_fn_tuple_out_2024/ffi.cpp
  type _ffi_ret_f32_bool (line 5) | struct _ffi_ret_f32_bool {

FILE: src/tests/snapshots/cpp_fn_tuple_out_2024/ffi.h
  function namespace (line 8) | namespace rust {

FILE: src/tests/snapshots/cpp_fn_tuple_out_2024/miniffi.rs
  function _ffi_fn_return_pair (line 4) | extern "C" fn _ffi_fn_return_pair(x: f32, y: bool) -> _ffi_ret_f32_bool {
  function _ffi_fn_rust_mem_leaked (line 10) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {
  function _ffi_fn_single_element_tuple (line 15) | extern "C" fn _ffi_fn_single_element_tuple(x: i32) -> i32 {
  type _ffi_ret_f32_bool (line 21) | struct _ffi_ret_f32_bool(f32, bool);

FILE: src/tests/snapshots/cpp_fn_vec_in_2021/ffi.cpp
  type _ffi_ret_ptr_2_usize (line 5) | struct _ffi_ret_ptr_2_usize {
  function _ffi_string_from_rust (line 34) | std::string _ffi_string_from_rust(const char* ptr, uintptr_t len, uintpt...
  function _ffi_write (line 45) | void _ffi_write(T val, std::vector<uint8_t> &buf) {
  function _ffi_vec_i32_to_rust (line 49) | void _ffi_vec_i32_to_rust(std::vector<int32_t>&& items, std::vector<uint...
  function _ffi_vec_vec_i32_to_rust (line 55) | void _ffi_vec_vec_i32_to_rust(std::vector<std::vector<int32_t>>&& items,...
  function _ffi_vec_f32_to_rust (line 63) | void _ffi_vec_f32_to_rust(std::vector<float>&& items, std::vector<uint8_...
  function _ffi_vec_f64_to_rust (line 69) | void _ffi_vec_f64_to_rust(std::vector<double>&& items, std::vector<uint8...
  function _ffi_vec_i16_to_rust (line 75) | void _ffi_vec_i16_to_rust(std::vector<int16_t>&& items, std::vector<uint...
  function _ffi_vec_i64_to_rust (line 81) | void _ffi_vec_i64_to_rust(std::vector<int64_t>&& items, std::vector<uint...
  function _ffi_vec_i8_to_rust (line 87) | void _ffi_vec_i8_to_rust(std::vector<int8_t>&& items, std::vector<uint8_...
  function _ffi_vec_isize_to_rust (line 93) | void _ffi_vec_isize_to_rust(std::vector<intptr_t>&& items, std::vector<u...
  function _ffi_vec_u16_to_rust (line 99) | void _ffi_vec_u16_to_rust(std::vector<uint16_t>&& items, std::vector<uin...
  function _ffi_vec_u32_to_rust (line 105) | void _ffi_vec_u32_to_rust(std::vector<uint32_t>&& items, std::vector<uin...
  function _ffi_vec_u64_to_rust (line 111) | void _ffi_vec_u64_to_rust(std::vector<uint64_t>&& items, std::vector<uin...
  function _ffi_vec_u8_to_rust (line 117) | void _ffi_vec_u8_to_rust(std::vector<uint8_t>&& items, std::vector<uint8...
  function _ffi_vec_usize_to_rust (line 123) | void _ffi_vec_usize_to_rust(std::vector<uintptr_t>&& items, std::vector<...

FILE: src/tests/snapshots/cpp_fn_vec_in_2021/ffi.h
  function namespace (line 9) | namespace rust {

FILE: src/tests/snapshots/cpp_fn_vec_in_2021/miniffi.rs
  function _ffi_alloc (line 4) | extern "C" fn _ffi_alloc(len: usize) -> *const u8 {
  function _ffi_buf_from_host (line 8) | fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) {
  function _ffi_fn_check_nested (line 14) | extern "C" fn _ffi_fn_check_nested(buf_ptr: *const u8, values_len: usize...
  function _ffi_fn_rust_mem_leaked (line 22) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {
  function _ffi_fn_sum_f32 (line 27) | extern "C" fn _ffi_fn_sum_f32(buf_ptr: *const u8, values_len: usize) -> ...
  function _ffi_fn_sum_f64 (line 35) | extern "C" fn _ffi_fn_sum_f64(buf_ptr: *const u8, values_len: usize) -> ...
  function _ffi_fn_sum_i16 (line 43) | extern "C" fn _ffi_fn_sum_i16(buf_ptr: *const u8, values_len: usize) -> ...
  function _ffi_fn_sum_i32 (line 51) | extern "C" fn _ffi_fn_sum_i32(buf_ptr: *const u8, values_len: usize) -> ...
  function _ffi_fn_sum_i64 (line 59) | extern "C" fn _ffi_fn_sum_i64(buf_ptr: *const u8, values_len: usize) -> ...
  function _ffi_fn_sum_i8 (line 67) | extern "C" fn _ffi_fn_sum_i8(buf_ptr: *const u8, values_len: usize) -> i8 {
  function _ffi_fn_sum_isize (line 75) | extern "C" fn _ffi_fn_sum_isize(buf_ptr: *const u8, values_len: usize) -...
  function _ffi_fn_sum_u16 (line 83) | extern "C" fn _ffi_fn_sum_u16(buf_ptr: *const u8, values_len: usize) -> ...
  function _ffi_fn_sum_u32 (line 91) | extern "C" fn _ffi_fn_sum_u32(buf_ptr: *const u8, values_len: usize) -> ...
  function _ffi_fn_sum_u64 (line 99) | extern "C" fn _ffi_fn_sum_u64(buf_ptr: *const u8, values_len: usize) -> ...
  function _ffi_fn_sum_u8 (line 107) | extern "C" fn _ffi_fn_sum_u8(buf_ptr: *const u8, values_len: usize) -> u8 {
  function _ffi_fn_sum_usize (line 115) | extern "C" fn _ffi_fn_sum_usize(buf_ptr: *const u8, values_len: usize) -...
  function _ffi_read (line 122) | fn _ffi_read<T: Copy>(ptr: &mut *const u8) -> T {
  type _ffi_ret_ptr_2_usize (line 129) | struct _ffi_ret_ptr_2_usize(*const u8, usize, usize);
  function _ffi_dealloc (line 132) | extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) {
  function _ffi_string_to_host (line 136) | fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) {
  function _ffi_vec_f32_from_cpp (line 141) | fn _ffi_vec_f32_from_cpp(len: usize, end: &mut *const u8) -> Vec<f32> {
  function _ffi_vec_f64_from_cpp (line 149) | fn _ffi_vec_f64_from_cpp(len: usize, end: &mut *const u8) -> Vec<f64> {
  function _ffi_vec_i16_from_cpp (line 157) | fn _ffi_vec_i16_from_cpp(len: usize, end: &mut *const u8) -> Vec<i16> {
  function _ffi_vec_i32_from_cpp (line 165) | fn _ffi_vec_i32_from_cpp(len: usize, end: &mut *const u8) -> Vec<i32> {
  function _ffi_vec_i64_from_cpp (line 173) | fn _ffi_vec_i64_from_cpp(len: usize, end: &mut *const u8) -> Vec<i64> {
  function _ffi_vec_i8_from_cpp (line 181) | fn _ffi_vec_i8_from_cpp(len: usize, end: &mut *const u8) -> Vec<i8> {
  function _ffi_vec_isize_from_cpp (line 189) | fn _ffi_vec_isize_from_cpp(len: usize, end: &mut *const u8) -> Vec<isize> {
  function _ffi_vec_u16_from_cpp (line 197) | fn _ffi_vec_u16_from_cpp(len: usize, end: &mut *const u8) -> Vec<u16> {
  function _ffi_vec_u32_from_cpp (line 205) | fn _ffi_vec_u32_from_cpp(len: usize, end: &mut *const u8) -> Vec<u32> {
  function _ffi_vec_u64_from_cpp (line 213) | fn _ffi_vec_u64_from_cpp(len: usize, end: &mut *const u8) -> Vec<u64> {
  function _ffi_vec_u8_from_cpp (line 221) | fn _ffi_vec_u8_from_cpp(len: usize, end: &mut *const u8) -> Vec<u8> {
  function _ffi_vec_usize_from_cpp (line 229) | fn _ffi_vec_usize_from_cpp(len: usize, end: &mut *const u8) -> Vec<usize> {
  function _ffi_vec_vec_i32_from_cpp (line 237) | fn _ffi_vec_vec_i32_from_cpp(len: usize, end: &mut *const u8) -> Vec<Vec...

FILE: src/tests/snapshots/cpp_fn_vec_in_2024/ffi.cpp
  type _ffi_ret_ptr_2_usize (line 5) | struct _ffi_ret_ptr_2_usize {
  function _ffi_string_from_rust (line 34) | std::string _ffi_string_from_rust(const char* ptr, uintptr_t len, uintpt...
  function _ffi_write (line 45) | void _ffi_write(T val, std::vector<uint8_t> &buf) {
  function _ffi_vec_i32_to_rust (line 49) | void _ffi_vec_i32_to_rust(std::vector<int32_t>&& items, std::vector<uint...
  function _ffi_vec_vec_i32_to_rust (line 55) | void _ffi_vec_vec_i32_to_rust(std::vector<std::vector<int32_t>>&& items,...
  function _ffi_vec_f32_to_rust (line 63) | void _ffi_vec_f32_to_rust(std::vector<float>&& items, std::vector<uint8_...
  function _ffi_vec_f64_to_rust (line 69) | void _ffi_vec_f64_to_rust(std::vector<double>&& items, std::vector<uint8...
  function _ffi_vec_i16_to_rust (line 75) | void _ffi_vec_i16_to_rust(std::vector<int16_t>&& items, std::vector<uint...
  function _ffi_vec_i64_to_rust (line 81) | void _ffi_vec_i64_to_rust(std::vector<int64_t>&& items, std::vector<uint...
  function _ffi_vec_i8_to_rust (line 87) | void _ffi_vec_i8_to_rust(std::vector<int8_t>&& items, std::vector<uint8_...
  function _ffi_vec_isize_to_rust (line 93) | void _ffi_vec_isize_to_rust(std::vector<intptr_t>&& items, std::vector<u...
  function _ffi_vec_u16_to_rust (line 99) | void _ffi_vec_u16_to_rust(std::vector<uint16_t>&& items, std::vector<uin...
  function _ffi_vec_u32_to_rust (line 105) | void _ffi_vec_u32_to_rust(std::vector<uint32_t>&& items, std::vector<uin...
  function _ffi_vec_u64_to_rust (line 111) | void _ffi_vec_u64_to_rust(std::vector<uint64_t>&& items, std::vector<uin...
  function _ffi_vec_u8_to_rust (line 117) | void _ffi_vec_u8_to_rust(std::vector<uint8_t>&& items, std::vector<uint8...
  function _ffi_vec_usize_to_rust (line 123) | void _ffi_vec_usize_to_rust(std::vector<uintptr_t>&& items, std::vector<...

FILE: src/tests/snapshots/cpp_fn_vec_in_2024/ffi.h
  function namespace (line 9) | namespace rust {

FILE: src/tests/snapshots/cpp_fn_vec_in_2024/miniffi.rs
  function _ffi_alloc (line 4) | extern "C" fn _ffi_alloc(len: usize) -> *const u8 {
  function _ffi_buf_from_host (line 8) | fn _ffi_buf_from_host(ptr: *const u8, end: *const u8) {
  function _ffi_fn_check_nested (line 14) | extern "C" fn _ffi_fn_check_nested(buf_ptr: *const u8, values_len: usize...
  function _ffi_fn_rust_mem_leaked (line 22) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {
  function _ffi_fn_sum_f32 (line 27) | extern "C" fn _ffi_fn_sum_f32(buf_ptr: *const u8, values_len: usize) -> ...
  function _ffi_fn_sum_f64 (line 35) | extern "C" fn _ffi_fn_sum_f64(buf_ptr: *const u8, values_len: usize) -> ...
  function _ffi_fn_sum_i16 (line 43) | extern "C" fn _ffi_fn_sum_i16(buf_ptr: *const u8, values_len: usize) -> ...
  function _ffi_fn_sum_i32 (line 51) | extern "C" fn _ffi_fn_sum_i32(buf_ptr: *const u8, values_len: usize) -> ...
  function _ffi_fn_sum_i64 (line 59) | extern "C" fn _ffi_fn_sum_i64(buf_ptr: *const u8, values_len: usize) -> ...
  function _ffi_fn_sum_i8 (line 67) | extern "C" fn _ffi_fn_sum_i8(buf_ptr: *const u8, values_len: usize) -> i8 {
  function _ffi_fn_sum_isize (line 75) | extern "C" fn _ffi_fn_sum_isize(buf_ptr: *const u8, values_len: usize) -...
  function _ffi_fn_sum_u16 (line 83) | extern "C" fn _ffi_fn_sum_u16(buf_ptr: *const u8, values_len: usize) -> ...
  function _ffi_fn_sum_u32 (line 91) | extern "C" fn _ffi_fn_sum_u32(buf_ptr: *const u8, values_len: usize) -> ...
  function _ffi_fn_sum_u64 (line 99) | extern "C" fn _ffi_fn_sum_u64(buf_ptr: *const u8, values_len: usize) -> ...
  function _ffi_fn_sum_u8 (line 107) | extern "C" fn _ffi_fn_sum_u8(buf_ptr: *const u8, values_len: usize) -> u8 {
  function _ffi_fn_sum_usize (line 115) | extern "C" fn _ffi_fn_sum_usize(buf_ptr: *const u8, values_len: usize) -...
  function _ffi_read (line 122) | fn _ffi_read<T: Copy>(ptr: &mut *const u8) -> T {
  type _ffi_ret_ptr_2_usize (line 129) | struct _ffi_ret_ptr_2_usize(*const u8, usize, usize);
  function _ffi_dealloc (line 132) | extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) {
  function _ffi_string_to_host (line 136) | fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) {
  function _ffi_vec_f32_from_cpp (line 141) | fn _ffi_vec_f32_from_cpp(len: usize, end: &mut *const u8) -> Vec<f32> {
  function _ffi_vec_f64_from_cpp (line 149) | fn _ffi_vec_f64_from_cpp(len: usize, end: &mut *const u8) -> Vec<f64> {
  function _ffi_vec_i16_from_cpp (line 157) | fn _ffi_vec_i16_from_cpp(len: usize, end: &mut *const u8) -> Vec<i16> {
  function _ffi_vec_i32_from_cpp (line 165) | fn _ffi_vec_i32_from_cpp(len: usize, end: &mut *const u8) -> Vec<i32> {
  function _ffi_vec_i64_from_cpp (line 173) | fn _ffi_vec_i64_from_cpp(len: usize, end: &mut *const u8) -> Vec<i64> {
  function _ffi_vec_i8_from_cpp (line 181) | fn _ffi_vec_i8_from_cpp(len: usize, end: &mut *const u8) -> Vec<i8> {
  function _ffi_vec_isize_from_cpp (line 189) | fn _ffi_vec_isize_from_cpp(len: usize, end: &mut *const u8) -> Vec<isize> {
  function _ffi_vec_u16_from_cpp (line 197) | fn _ffi_vec_u16_from_cpp(len: usize, end: &mut *const u8) -> Vec<u16> {
  function _ffi_vec_u32_from_cpp (line 205) | fn _ffi_vec_u32_from_cpp(len: usize, end: &mut *const u8) -> Vec<u32> {
  function _ffi_vec_u64_from_cpp (line 213) | fn _ffi_vec_u64_from_cpp(len: usize, end: &mut *const u8) -> Vec<u64> {
  function _ffi_vec_u8_from_cpp (line 221) | fn _ffi_vec_u8_from_cpp(len: usize, end: &mut *const u8) -> Vec<u8> {
  function _ffi_vec_usize_from_cpp (line 229) | fn _ffi_vec_usize_from_cpp(len: usize, end: &mut *const u8) -> Vec<usize> {
  function _ffi_vec_vec_i32_from_cpp (line 237) | fn _ffi_vec_vec_i32_from_cpp(len: usize, end: &mut *const u8) -> Vec<Vec...

FILE: src/tests/snapshots/cpp_fn_vec_out_2021/ffi.cpp
  type _ffi_ret_ptr_2_usize (line 5) | struct _ffi_ret_ptr_2_usize {
  function T (line 23) | T _ffi_read(const uint8_t* &ptr) {
  function _ffi_vec_i32_from_rust (line 30) | std::vector<int32_t> _ffi_vec_i32_from_rust(uintptr_t len, const uint8_t...
  function _ffi_vec_vec_i32_from_rust (line 40) | std::vector<std::vector<int32_t>> _ffi_vec_vec_i32_from_rust(uintptr_t l...

FILE: src/tests/snapshots/cpp_fn_vec_out_2021/ffi.h
  function namespace (line 8) | namespace rust {

FILE: src/tests/snapshots/cpp_fn_vec_out_2021/miniffi.rs
  function _ffi_dealloc (line 4) | extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) {
  function _ffi_buf_to_host (line 8) | fn _ffi_buf_to_host(buf: Vec<u8>) -> (*const u8, usize) {
  function _ffi_fn_check_nested (line 14) | extern "C" fn _ffi_fn_check_nested() -> _ffi_ret_ptr_2_usize {
  function _ffi_fn_get_vec (line 24) | extern "C" fn _ffi_fn_get_vec(n: i32) -> _ffi_ret_ptr_2_usize {
  function _ffi_fn_rust_mem_leaked (line 34) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {
  type _ffi_ret_ptr_2_usize (line 39) | struct _ffi_ret_ptr_2_usize(*const u8, usize, usize);
  function _ffi_vec_i32_to_cpp (line 41) | fn _ffi_vec_i32_to_cpp(items: Vec<i32>, buf: &mut Vec<u8>) {
  function _ffi_vec_vec_i32_to_cpp (line 47) | fn _ffi_vec_vec_i32_to_cpp(items: Vec<Vec<i32>>, buf: &mut Vec<u8>) {
  function _ffi_write (line 54) | fn _ffi_write<T: Copy>(val: T, buf: &mut Vec<u8>) {

FILE: src/tests/snapshots/cpp_fn_vec_out_2024/ffi.cpp
  type _ffi_ret_ptr_2_usize (line 5) | struct _ffi_ret_ptr_2_usize {
  function T (line 23) | T _ffi_read(const uint8_t* &ptr) {
  function _ffi_vec_i32_from_rust (line 30) | std::vector<int32_t> _ffi_vec_i32_from_rust(uintptr_t len, const uint8_t...
  function _ffi_vec_vec_i32_from_rust (line 40) | std::vector<std::vector<int32_t>> _ffi_vec_vec_i32_from_rust(uintptr_t l...

FILE: src/tests/snapshots/cpp_fn_vec_out_2024/ffi.h
  function namespace (line 8) | namespace rust {

FILE: src/tests/snapshots/cpp_fn_vec_out_2024/miniffi.rs
  function _ffi_dealloc (line 4) | extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) {
  function _ffi_buf_to_host (line 8) | fn _ffi_buf_to_host(buf: Vec<u8>) -> (*const u8, usize) {
  function _ffi_fn_check_nested (line 14) | extern "C" fn _ffi_fn_check_nested() -> _ffi_ret_ptr_2_usize {
  function _ffi_fn_get_vec (line 24) | extern "C" fn _ffi_fn_get_vec(n: i32) -> _ffi_ret_ptr_2_usize {
  function _ffi_fn_rust_mem_leaked (line 34) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {
  type _ffi_ret_ptr_2_usize (line 39) | struct _ffi_ret_ptr_2_usize(*const u8, usize, usize);
  function _ffi_vec_i32_to_cpp (line 41) | fn _ffi_vec_i32_to_cpp(items: Vec<i32>, buf: &mut Vec<u8>) {
  function _ffi_vec_vec_i32_to_cpp (line 47) | fn _ffi_vec_vec_i32_to_cpp(items: Vec<Vec<i32>>, buf: &mut Vec<u8>) {
  function _ffi_write (line 54) | fn _ffi_write<T: Copy>(val: T, buf: &mut Vec<u8>) {

FILE: src/tests/snapshots/cpp_trait_enum_2021/ffi.cpp
  type _ffi_Box_Foo (line 17) | struct _ffi_Box_Foo final : rust::Foo {
    method _ffi_Box_Foo (line 18) | _ffi_Box_Foo(const void* ptr) : _self(ptr) {}

FILE: src/tests/snapshots/cpp_trait_enum_2021/ffi.h
  function namespace (line 8) | namespace rust {

FILE: src/tests/snapshots/cpp_trait_enum_2021/miniffi.rs
  function _ffi_Box_Foo__get_enum (line 4) | extern "C" fn _ffi_Box_Foo__get_enum(_self: *const u8) -> i32 {
  function _ffi_Box_Foo__set_enum (line 10) | extern "C" fn _ffi_Box_Foo__set_enum(_self: *const u8, bar_raw: i32) {
  function _ffi_drop_Box_Foo (line 16) | extern "C" fn _ffi_drop_Box_Foo(ptr: *const u8) {
  function _ffi_enum_Bar_from_cpp (line 21) | fn _ffi_enum_Bar_from_cpp(val: i32) -> Bar {
  function _ffi_fn_get_foo (line 31) | extern "C" fn _ffi_fn_get_foo() -> *const u8 {
  function _ffi_fn_rust_mem_leaked (line 36) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {

FILE: src/tests/snapshots/cpp_trait_enum_2024/ffi.cpp
  type _ffi_Box_Foo (line 17) | struct _ffi_Box_Foo final : rust::Foo {
    method _ffi_Box_Foo (line 18) | _ffi_Box_Foo(const void* ptr) : _self(ptr) {}

FILE: src/tests/snapshots/cpp_trait_enum_2024/ffi.h
  function namespace (line 8) | namespace rust {

FILE: src/tests/snapshots/cpp_trait_enum_2024/miniffi.rs
  function _ffi_Box_Foo__get_enum (line 4) | extern "C" fn _ffi_Box_Foo__get_enum(_self: *const u8) -> i32 {
  function _ffi_Box_Foo__set_enum (line 10) | extern "C" fn _ffi_Box_Foo__set_enum(_self: *const u8, bar_raw: i32) {
  function _ffi_drop_Box_Foo (line 16) | extern "C" fn _ffi_drop_Box_Foo(ptr: *const u8) {
  function _ffi_enum_Bar_from_cpp (line 21) | fn _ffi_enum_Bar_from_cpp(val: i32) -> Bar {
  function _ffi_fn_get_foo (line 31) | extern "C" fn _ffi_fn_get_foo() -> *const u8 {
  function _ffi_fn_rust_mem_leaked (line 36) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {

FILE: src/tests/snapshots/cpp_trait_export_2021/ffi.cpp
  type _ffi_Box_Adder (line 20) | struct _ffi_Box_Adder final : rust::Adder {
    method _ffi_Box_Adder (line 21) | _ffi_Box_Adder(const void* ptr) : _self(ptr) {}
  type _ffi_Rc_Adder (line 27) | struct _ffi_Rc_Adder final : rust::Adder {
    method _ffi_Rc_Adder (line 28) | _ffi_Rc_Adder(const void* ptr) : _self(ptr) {}

FILE: src/tests/snapshots/cpp_trait_export_2021/ffi.h
  function namespace (line 8) | namespace rust {

FILE: src/tests/snapshots/cpp_trait_export_2021/miniffi.rs
  function _ffi_Box_Adder__add (line 4) | extern "C" fn _ffi_Box_Adder__add(_self: *const u8, x: i32) -> i32 {
  function _ffi_Rc_Adder__add (line 10) | extern "C" fn _ffi_Rc_Adder__add(_self: *const u8, x: i32) -> i32 {
  function _ffi_drop_Box_Adder (line 16) | extern "C" fn _ffi_drop_Box_Adder(ptr: *const u8) {
  function _ffi_drop_Rc_Adder (line 21) | extern "C" fn _ffi_drop_Rc_Adder(ptr: *const u8) {
  function _ffi_fn_get_adder_box (line 26) | extern "C" fn _ffi_fn_get_adder_box(x: i32) -> *const u8 {
  function _ffi_fn_get_adder_rc (line 31) | extern "C" fn _ffi_fn_get_adder_rc(x: i32) -> *const u8 {
  function _ffi_fn_get_counter (line 36) | extern "C" fn _ffi_fn_get_counter() -> u32 {
  function _ffi_fn_rust_mem_leaked (line 41) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {

FILE: src/tests/snapshots/cpp_trait_export_2024/ffi.cpp
  type _ffi_Box_Adder (line 20) | struct _ffi_Box_Adder final : rust::Adder {
    method _ffi_Box_Adder (line 21) | _ffi_Box_Adder(const void* ptr) : _self(ptr) {}
  type _ffi_Rc_Adder (line 27) | struct _ffi_Rc_Adder final : rust::Adder {
    method _ffi_Rc_Adder (line 28) | _ffi_Rc_Adder(const void* ptr) : _self(ptr) {}

FILE: src/tests/snapshots/cpp_trait_export_2024/ffi.h
  function namespace (line 8) | namespace rust {

FILE: src/tests/snapshots/cpp_trait_export_2024/miniffi.rs
  function _ffi_Box_Adder__add (line 4) | extern "C" fn _ffi_Box_Adder__add(_self: *const u8, x: i32) -> i32 {
  function _ffi_Rc_Adder__add (line 10) | extern "C" fn _ffi_Rc_Adder__add(_self: *const u8, x: i32) -> i32 {
  function _ffi_drop_Box_Adder (line 16) | extern "C" fn _ffi_drop_Box_Adder(ptr: *const u8) {
  function _ffi_drop_Rc_Adder (line 21) | extern "C" fn _ffi_drop_Rc_Adder(ptr: *const u8) {
  function _ffi_fn_get_adder_box (line 26) | extern "C" fn _ffi_fn_get_adder_box(x: i32) -> *const u8 {
  function _ffi_fn_get_adder_rc (line 31) | extern "C" fn _ffi_fn_get_adder_rc(x: i32) -> *const u8 {
  function _ffi_fn_get_counter (line 36) | extern "C" fn _ffi_fn_get_counter() -> u32 {
  function _ffi_fn_rust_mem_leaked (line 41) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {

FILE: src/tests/snapshots/cpp_trait_export_import_2021/ffi.cpp
  type _ffi_Rc_Exported (line 17) | struct _ffi_Rc_Exported final : rust::Exported {
    method _ffi_Rc_Exported (line 18) | _ffi_Rc_Exported(const void* ptr) : _self(ptr) {}
  function _ffi_cpp_Rc_Imported__add (line 28) | int32_t _ffi_cpp_Rc_Imported__add(std::shared_ptr<rust::Imported>* _self...
  function _ffi_cpp_drop_Rc_Imported (line 32) | void _ffi_cpp_drop_Rc_Imported(std::shared_ptr<rust::Imported>* self) {

FILE: src/tests/snapshots/cpp_trait_export_import_2021/ffi.h
  function namespace (line 8) | namespace rust {

FILE: src/tests/snapshots/cpp_trait_export_import_2021/miniffi.rs
  function _ffi_Rc_Exported__run (line 4) | extern "C" fn _ffi_Rc_Exported__run(_self: *const u8, imported_ptr: *con...
  function _ffi_drop_Rc_Exported (line 10) | extern "C" fn _ffi_drop_Rc_Exported(ptr: *const u8) {
  function _ffi_fn_get_counter (line 15) | extern "C" fn _ffi_fn_get_counter() -> u32 {
  function _ffi_fn_get_exported (line 20) | extern "C" fn _ffi_fn_get_exported() -> *const u8 {
  function _ffi_fn_rust_mem_leaked (line 25) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {
  type _ffi_rs_Rc_Imported (line 30) | struct _ffi_rs_Rc_Imported(*const u8);
  method drop (line 33) | fn drop(&mut self) {
  method add (line 40) | fn add(&self, x: i32, y: i32) -> i32 {

FILE: src/tests/snapshots/cpp_trait_export_import_2024/ffi.cpp
  type _ffi_Rc_Exported (line 17) | struct _ffi_Rc_Exported final : rust::Exported {
    method _ffi_Rc_Exported (line 18) | _ffi_Rc_Exported(const void* ptr) : _self(ptr) {}
  function _ffi_cpp_Rc_Imported__add (line 28) | int32_t _ffi_cpp_Rc_Imported__add(std::shared_ptr<rust::Imported>* _self...
  function _ffi_cpp_drop_Rc_Imported (line 32) | void _ffi_cpp_drop_Rc_Imported(std::shared_ptr<rust::Imported>* self) {

FILE: src/tests/snapshots/cpp_trait_export_import_2024/ffi.h
  function namespace (line 8) | namespace rust {

FILE: src/tests/snapshots/cpp_trait_export_import_2024/miniffi.rs
  function _ffi_Rc_Exported__run (line 4) | extern "C" fn _ffi_Rc_Exported__run(_self: *const u8, imported_ptr: *con...
  function _ffi_drop_Rc_Exported (line 10) | extern "C" fn _ffi_drop_Rc_Exported(ptr: *const u8) {
  function _ffi_fn_get_counter (line 15) | extern "C" fn _ffi_fn_get_counter() -> u32 {
  function _ffi_fn_get_exported (line 20) | extern "C" fn _ffi_fn_get_exported() -> *const u8 {
  function _ffi_fn_rust_mem_leaked (line 25) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {
  type _ffi_rs_Rc_Imported (line 30) | struct _ffi_rs_Rc_Imported(*const u8);
  method drop (line 33) | fn drop(&mut self) {
  method add (line 40) | fn add(&self, x: i32, y: i32) -> i32 {

FILE: src/tests/snapshots/cpp_trait_export_nested_2021/ffi.cpp
  type _ffi_Rc_Adder (line 20) | struct _ffi_Rc_Adder final : rust::Adder {
    method _ffi_Rc_Adder (line 21) | _ffi_Rc_Adder(const void* ptr) : _self(ptr) {}
  type _ffi_Rc_Getter (line 27) | struct _ffi_Rc_Getter final : rust::Getter {
    method _ffi_Rc_Getter (line 28) | _ffi_Rc_Getter(const void* ptr) : _self(ptr) {}

FILE: src/tests/snapshots/cpp_trait_export_nested_2021/ffi.h
  function namespace (line 8) | namespace rust {

FILE: src/tests/snapshots/cpp_trait_export_nested_2021/miniffi.rs
  function _ffi_Rc_Adder__add (line 4) | extern "C" fn _ffi_Rc_Adder__add(_self: *const u8, x: i32, y: i32) -> i32 {
  function _ffi_Rc_Getter__get_adder (line 10) | extern "C" fn _ffi_Rc_Getter__get_adder(_self: *const u8) -> *const u8 {
  function _ffi_drop_Rc_Adder (line 16) | extern "C" fn _ffi_drop_Rc_Adder(ptr: *const u8) {
  function _ffi_drop_Rc_Getter (line 21) | extern "C" fn _ffi_drop_Rc_Getter(ptr: *const u8) {
  function _ffi_fn_get_adder_counter (line 26) | extern "C" fn _ffi_fn_get_adder_counter() -> u32 {
  function _ffi_fn_get_getter (line 31) | extern "C" fn _ffi_fn_get_getter() -> *const u8 {
  function _ffi_fn_get_getter_counter (line 36) | extern "C" fn _ffi_fn_get_getter_counter() -> u32 {
  function _ffi_fn_rust_mem_leaked (line 41) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {

FILE: src/tests/snapshots/cpp_trait_export_nested_2024/ffi.cpp
  type _ffi_Rc_Adder (line 20) | struct _ffi_Rc_Adder final : rust::Adder {
    method _ffi_Rc_Adder (line 21) | _ffi_Rc_Adder(const void* ptr) : _self(ptr) {}
  type _ffi_Rc_Getter (line 27) | struct _ffi_Rc_Getter final : rust::Getter {
    method _ffi_Rc_Getter (line 28) | _ffi_Rc_Getter(const void* ptr) : _self(ptr) {}

FILE: src/tests/snapshots/cpp_trait_export_nested_2024/ffi.h
  function namespace (line 8) | namespace rust {

FILE: src/tests/snapshots/cpp_trait_export_nested_2024/miniffi.rs
  function _ffi_Rc_Adder__add (line 4) | extern "C" fn _ffi_Rc_Adder__add(_self: *const u8, x: i32, y: i32) -> i32 {
  function _ffi_Rc_Getter__get_adder (line 10) | extern "C" fn _ffi_Rc_Getter__get_adder(_self: *const u8) -> *const u8 {
  function _ffi_drop_Rc_Adder (line 16) | extern "C" fn _ffi_drop_Rc_Adder(ptr: *const u8) {
  function _ffi_drop_Rc_Getter (line 21) | extern "C" fn _ffi_drop_Rc_Getter(ptr: *const u8) {
  function _ffi_fn_get_adder_counter (line 26) | extern "C" fn _ffi_fn_get_adder_counter() -> u32 {
  function _ffi_fn_get_getter (line 31) | extern "C" fn _ffi_fn_get_getter() -> *const u8 {
  function _ffi_fn_get_getter_counter (line 36) | extern "C" fn _ffi_fn_get_getter_counter() -> u32 {
  function _ffi_fn_rust_mem_leaked (line 41) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {

FILE: src/tests/snapshots/cpp_trait_import_2021/ffi.cpp
  function _ffi_cpp_Box_Adder__add (line 15) | int32_t _ffi_cpp_Box_Adder__add(rust::Adder* _self, int32_t y) {
  function _ffi_cpp_Rc_Adder__add (line 19) | int32_t _ffi_cpp_Rc_Adder__add(std::shared_ptr<rust::Adder>* _self, int3...
  function _ffi_cpp_drop_Box_Adder (line 23) | void _ffi_cpp_drop_Box_Adder(rust::Adder* self) {
  function _ffi_cpp_drop_Rc_Adder (line 27) | void _ffi_cpp_drop_Rc_Adder(std::shared_ptr<rust::Adder>* self) {

FILE: src/tests/snapshots/cpp_trait_import_2021/ffi.h
  function namespace (line 8) | namespace rust {

FILE: src/tests/snapshots/cpp_trait_import_2021/miniffi.rs
  function _ffi_fn_rust_mem_leaked (line 4) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {
  function _ffi_fn_set_adder_box (line 9) | extern "C" fn _ffi_fn_set_adder_box(adder_ptr: *const u8) -> i32 {
  function _ffi_fn_set_adder_rc (line 14) | extern "C" fn _ffi_fn_set_adder_rc(adder_ptr: *const u8) -> i32 {
  type _ffi_rs_Box_Adder (line 19) | struct _ffi_rs_Box_Adder(*const u8);
  method drop (line 22) | fn drop(&mut self) {
  method add (line 29) | fn add(&self, y: i32) -> i32 {
  type _ffi_rs_Rc_Adder (line 36) | struct _ffi_rs_Rc_Adder(*const u8);
  method drop (line 39) | fn drop(&mut self) {
  method add (line 46) | fn add(&self, y: i32) -> i32 {

FILE: src/tests/snapshots/cpp_trait_import_2024/ffi.cpp
  function _ffi_cpp_Box_Adder__add (line 15) | int32_t _ffi_cpp_Box_Adder__add(rust::Adder* _self, int32_t y) {
  function _ffi_cpp_Rc_Adder__add (line 19) | int32_t _ffi_cpp_Rc_Adder__add(std::shared_ptr<rust::Adder>* _self, int3...
  function _ffi_cpp_drop_Box_Adder (line 23) | void _ffi_cpp_drop_Box_Adder(rust::Adder* self) {
  function _ffi_cpp_drop_Rc_Adder (line 27) | void _ffi_cpp_drop_Rc_Adder(std::shared_ptr<rust::Adder>* self) {

FILE: src/tests/snapshots/cpp_trait_import_2024/ffi.h
  function namespace (line 8) | namespace rust {

FILE: src/tests/snapshots/cpp_trait_import_2024/miniffi.rs
  function _ffi_fn_rust_mem_leaked (line 4) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {
  function _ffi_fn_set_adder_box (line 9) | extern "C" fn _ffi_fn_set_adder_box(adder_ptr: *const u8) -> i32 {
  function _ffi_fn_set_adder_rc (line 14) | extern "C" fn _ffi_fn_set_adder_rc(adder_ptr: *const u8) -> i32 {
  type _ffi_rs_Box_Adder (line 19) | struct _ffi_rs_Box_Adder(*const u8);
  method drop (line 22) | fn drop(&mut self) {
  method add (line 29) | fn add(&self, y: i32) -> i32 {
  type _ffi_rs_Rc_Adder (line 36) | struct _ffi_rs_Rc_Adder(*const u8);
  method drop (line 39) | fn drop(&mut self) {
  method add (line 46) | fn add(&self, y: i32) -> i32 {

FILE: src/tests/snapshots/cpp_trait_import_export_2021/ffi.cpp
  type _ffi_Rc_Exported (line 17) | struct _ffi_Rc_Exported final : rust::Exported {
    method _ffi_Rc_Exported (line 18) | _ffi_Rc_Exported(const void* ptr) : _self(ptr) {}
  function _ffi_cpp_Rc_Imported__run (line 28) | int32_t _ffi_cpp_Rc_Imported__run(std::shared_ptr<rust::Imported>* _self...
  function _ffi_cpp_drop_Rc_Imported (line 33) | void _ffi_cpp_drop_Rc_Imported(std::shared_ptr<rust::Imported>* self) {

FILE: src/tests/snapshots/cpp_trait_import_export_2021/ffi.h
  function namespace (line 8) | namespace rust {

FILE: src/tests/snapshots/cpp_trait_import_export_2021/miniffi.rs
  function _ffi_Rc_Exported__add (line 4) | extern "C" fn _ffi_Rc_Exported__add(_self: *const u8, x: i32, y: i32) ->...
  function _ffi_drop_Rc_Exported (line 10) | extern "C" fn _ffi_drop_Rc_Exported(ptr: *const u8) {
  function _ffi_fn_get_counter (line 15) | extern "C" fn _ffi_fn_get_counter() -> u32 {
  function _ffi_fn_rust_mem_leaked (line 20) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {
  function _ffi_fn_set_imported (line 25) | extern "C" fn _ffi_fn_set_imported(imported_ptr: *const u8) -> i32 {
  type _ffi_rs_Rc_Imported (line 30) | struct _ffi_rs_Rc_Imported(*const u8);
  method drop (line 33) | fn drop(&mut self) {
  method run (line 40) | fn run(&self, exported: std::rc::Rc<dyn Exported>) -> i32 {

FILE: src/tests/snapshots/cpp_trait_import_export_2024/ffi.cpp
  type _ffi_Rc_Exported (line 17) | struct _ffi_Rc_Exported final : rust::Exported {
    method _ffi_Rc_Exported (line 18) | _ffi_Rc_Exported(const void* ptr) : _self(ptr) {}
  function _ffi_cpp_Rc_Imported__run (line 28) | int32_t _ffi_cpp_Rc_Imported__run(std::shared_ptr<rust::Imported>* _self...
  function _ffi_cpp_drop_Rc_Imported (line 33) | void _ffi_cpp_drop_Rc_Imported(std::shared_ptr<rust::Imported>* self) {

FILE: src/tests/snapshots/cpp_trait_import_export_2024/ffi.h
  function namespace (line 8) | namespace rust {

FILE: src/tests/snapshots/cpp_trait_import_export_2024/miniffi.rs
  function _ffi_Rc_Exported__add (line 4) | extern "C" fn _ffi_Rc_Exported__add(_self: *const u8, x: i32, y: i32) ->...
  function _ffi_drop_Rc_Exported (line 10) | extern "C" fn _ffi_drop_Rc_Exported(ptr: *const u8) {
  function _ffi_fn_get_counter (line 15) | extern "C" fn _ffi_fn_get_counter() -> u32 {
  function _ffi_fn_rust_mem_leaked (line 20) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {
  function _ffi_fn_set_imported (line 25) | extern "C" fn _ffi_fn_set_imported(imported_ptr: *const u8) -> i32 {
  type _ffi_rs_Rc_Imported (line 30) | struct _ffi_rs_Rc_Imported(*const u8);
  method drop (line 33) | fn drop(&mut self) {
  method run (line 40) | fn run(&self, exported: std::rc::Rc<dyn Exported>) -> i32 {

FILE: src/tests/snapshots/cpp_trait_import_nested_2021/ffi.cpp
  function _ffi_cpp_Rc_Adder__add (line 14) | int32_t _ffi_cpp_Rc_Adder__add(std::shared_ptr<rust::Adder>* _self, int3...
  function _ffi_cpp_drop_Rc_Adder (line 22) | void _ffi_cpp_drop_Rc_Adder(std::shared_ptr<rust::Adder>* self) {
  function _ffi_cpp_drop_Rc_Getter (line 26) | void _ffi_cpp_drop_Rc_Getter(std::shared_ptr<rust::Getter>* self) {

FILE: src/tests/snapshots/cpp_trait_import_nested_2021/ffi.h
  function namespace (line 8) | namespace rust {

FILE: src/tests/snapshots/cpp_trait_import_nested_2021/miniffi.rs
  function _ffi_fn_rust_mem_leaked (line 4) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {
  function _ffi_fn_set_getter (line 9) | extern "C" fn _ffi_fn_set_getter(getter_ptr: *const u8) -> i32 {
  type _ffi_rs_Rc_Adder (line 14) | struct _ffi_rs_Rc_Adder(*const u8);
  method drop (line 17) | fn drop(&mut self) {
  method add (line 24) | fn add(&self, x: i32, y: i32) -> i32 {
  type _ffi_rs_Rc_Getter (line 31) | struct _ffi_rs_Rc_Getter(*const u8);
  method drop (line 34) | fn drop(&mut self) {
  method get_adder (line 41) | fn get_adder(&self) -> std::rc::Rc<dyn Adder> {

FILE: src/tests/snapshots/cpp_trait_import_nested_2024/ffi.cpp
  function _ffi_cpp_Rc_Adder__add (line 14) | int32_t _ffi_cpp_Rc_Adder__add(std::shared_ptr<rust::Adder>* _self, int3...
  function _ffi_cpp_drop_Rc_Adder (line 22) | void _ffi_cpp_drop_Rc_Adder(std::shared_ptr<rust::Adder>* self) {
  function _ffi_cpp_drop_Rc_Getter (line 26) | void _ffi_cpp_drop_Rc_Getter(std::shared_ptr<rust::Getter>* self) {

FILE: src/tests/snapshots/cpp_trait_import_nested_2024/ffi.h
  function namespace (line 8) | namespace rust {

FILE: src/tests/snapshots/cpp_trait_import_nested_2024/miniffi.rs
  function _ffi_fn_rust_mem_leaked (line 4) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {
  function _ffi_fn_set_getter (line 9) | extern "C" fn _ffi_fn_set_getter(getter_ptr: *const u8) -> i32 {
  type _ffi_rs_Rc_Adder (line 14) | struct _ffi_rs_Rc_Adder(*const u8);
  method drop (line 17) | fn drop(&mut self) {
  method add (line 24) | fn add(&self, x: i32, y: i32) -> i32 {
  type _ffi_rs_Rc_Getter (line 31) | struct _ffi_rs_Rc_Getter(*const u8);
  method drop (line 34) | fn drop(&mut self) {
  method get_adder (line 41) | fn get_adder(&self) -> std::rc::Rc<dyn Adder> {

FILE: src/tests/snapshots/cpp_trait_import_struct_in_2021/ffi.cpp
  function _ffi_cpp_Rc_StructIn__empty_struct (line 16) | int32_t _ffi_cpp_Rc_StructIn__empty_struct(std::shared_ptr<rust::StructI...
  function _ffi_cpp_Rc_StructIn__multiply_pairs (line 21) | float _ffi_cpp_Rc_StructIn__multiply_pairs(std::shared_ptr<rust::StructI...
  function _ffi_cpp_Rc_StructIn__single_element_struct (line 27) | int32_t _ffi_cpp_Rc_StructIn__single_element_struct(std::shared_ptr<rust...
  function _ffi_cpp_drop_Rc_StructIn (line 33) | void _ffi_cpp_drop_Rc_StructIn(std::shared_ptr<rust::StructIn>* self) {

FILE: src/tests/snapshots/cpp_trait_import_struct_in_2021/ffi.h
  function namespace (line 8) | namespace rust {

FILE: src/tests/snapshots/cpp_trait_import_struct_in_2021/miniffi.rs
  function _ffi_fn_rust_mem_leaked (line 4) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {
  function _ffi_fn_set_empty_struct (line 9) | extern "C" fn _ffi_fn_set_empty_struct(struct_in_ptr: *const u8) -> i32 {
  function _ffi_fn_set_multiply_pairs (line 14) | extern "C" fn _ffi_fn_set_multiply_pairs(struct_in_ptr: *const u8) -> f32 {
  function _ffi_fn_set_single_element_struct (line 19) | extern "C" fn _ffi_fn_set_single_element_struct(struct_in_ptr: *const u8...
  type _ffi_rs_Rc_StructIn (line 24) | struct _ffi_rs_Rc_StructIn(*const u8);
  method drop (line 27) | fn drop(&mut self) {
  method empty_struct (line 34) | fn empty_struct(&self, x: i32, foo: EmptyStruct, y: i32) -> i32 {
  method single_element_struct (line 40) | fn single_element_struct(&self, x: SingleElementStruct, y: SingleElement...
  method multiply_pairs (line 45) | fn multiply_pairs(&self, ab: PairStruct, cd: PairStruct) -> f32 {

FILE: src/tests/snapshots/cpp_trait_import_struct_in_2024/ffi.cpp
  function _ffi_cpp_Rc_StructIn__empty_struct (line 16) | int32_t _ffi_cpp_Rc_StructIn__empty_struct(std::shared_ptr<rust::StructI...
  function _ffi_cpp_Rc_StructIn__multiply_pairs (line 21) | float _ffi_cpp_Rc_StructIn__multiply_pairs(std::shared_ptr<rust::StructI...
  function _ffi_cpp_Rc_StructIn__single_element_struct (line 27) | int32_t _ffi_cpp_Rc_StructIn__single_element_struct(std::shared_ptr<rust...
  function _ffi_cpp_drop_Rc_StructIn (line 33) | void _ffi_cpp_drop_Rc_StructIn(std::shared_ptr<rust::StructIn>* self) {

FILE: src/tests/snapshots/cpp_trait_import_struct_in_2024/ffi.h
  function namespace (line 8) | namespace rust {

FILE: src/tests/snapshots/cpp_trait_import_struct_in_2024/miniffi.rs
  function _ffi_fn_rust_mem_leaked (line 4) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {
  function _ffi_fn_set_empty_struct (line 9) | extern "C" fn _ffi_fn_set_empty_struct(struct_in_ptr: *const u8) -> i32 {
  function _ffi_fn_set_multiply_pairs (line 14) | extern "C" fn _ffi_fn_set_multiply_pairs(struct_in_ptr: *const u8) -> f32 {
  function _ffi_fn_set_single_element_struct (line 19) | extern "C" fn _ffi_fn_set_single_element_struct(struct_in_ptr: *const u8...
  type _ffi_rs_Rc_StructIn (line 24) | struct _ffi_rs_Rc_StructIn(*const u8);
  method drop (line 27) | fn drop(&mut self) {
  method empty_struct (line 34) | fn empty_struct(&self, x: i32, foo: EmptyStruct, y: i32) -> i32 {
  method single_element_struct (line 40) | fn single_element_struct(&self, x: SingleElementStruct, y: SingleElement...
  method multiply_pairs (line 45) | fn multiply_pairs(&self, ab: PairStruct, cd: PairStruct) -> f32 {

FILE: src/tests/snapshots/cpp_trait_import_tuple_in_2021/ffi.cpp
  function _ffi_cpp_Rc_TupleIn__empty_tuple (line 16) | int32_t _ffi_cpp_Rc_TupleIn__empty_tuple(std::shared_ptr<rust::TupleIn>*...
  function _ffi_cpp_Rc_TupleIn__multiply_pairs (line 21) | float _ffi_cpp_Rc_TupleIn__multiply_pairs(std::shared_ptr<rust::TupleIn>...
  function _ffi_cpp_Rc_TupleIn__single_element_tuple (line 27) | int32_t _ffi_cpp_Rc_TupleIn__single_element_tuple(std::shared_ptr<rust::...
  function _ffi_cpp_drop_Rc_TupleIn (line 33) | void _ffi_cpp_drop_Rc_TupleIn(std::shared_ptr<rust::TupleIn>* self) {

FILE: src/tests/snapshots/cpp_trait_import_tuple_in_2021/ffi.h
  function namespace (line 9) | namespace rust {

FILE: src/tests/snapshots/cpp_trait_import_tuple_in_2021/miniffi.rs
  function _ffi_fn_rust_mem_leaked (line 4) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {
  function _ffi_fn_set_empty_tuple (line 9) | extern "C" fn _ffi_fn_set_empty_tuple(tuple_in_ptr: *const u8) -> i32 {
  function _ffi_fn_set_multiply_pairs (line 14) | extern "C" fn _ffi_fn_set_multiply_pairs(tuple_in_ptr: *const u8) -> f32 {
  function _ffi_fn_set_single_element_tuple (line 19) | extern "C" fn _ffi_fn_set_single_element_tuple(tuple_in_ptr: *const u8) ...
  type _ffi_rs_Rc_TupleIn (line 24) | struct _ffi_rs_Rc_TupleIn(*const u8);
  method drop (line 27) | fn drop(&mut self) {
  method empty_tuple (line 34) | fn empty_tuple(&self, x: i32, foo: (), y: i32) -> i32 {
  method single_element_tuple (line 40) | fn single_element_tuple(&self, x: (i32,), y: (i32,)) -> i32 {
  method multiply_pairs (line 45) | fn multiply_pairs(&self, ab: (f32, f32), cd: (f32, f32)) -> f32 {

FILE: src/tests/snapshots/cpp_trait_import_tuple_in_2024/ffi.cpp
  function _ffi_cpp_Rc_TupleIn__empty_tuple (line 16) | int32_t _ffi_cpp_Rc_TupleIn__empty_tuple(std::shared_ptr<rust::TupleIn>*...
  function _ffi_cpp_Rc_TupleIn__multiply_pairs (line 21) | float _ffi_cpp_Rc_TupleIn__multiply_pairs(std::shared_ptr<rust::TupleIn>...
  function _ffi_cpp_Rc_TupleIn__single_element_tuple (line 27) | int32_t _ffi_cpp_Rc_TupleIn__single_element_tuple(std::shared_ptr<rust::...
  function _ffi_cpp_drop_Rc_TupleIn (line 33) | void _ffi_cpp_drop_Rc_TupleIn(std::shared_ptr<rust::TupleIn>* self) {

FILE: src/tests/snapshots/cpp_trait_import_tuple_in_2024/ffi.h
  function namespace (line 9) | namespace rust {

FILE: src/tests/snapshots/cpp_trait_import_tuple_in_2024/miniffi.rs
  function _ffi_fn_rust_mem_leaked (line 4) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {
  function _ffi_fn_set_empty_tuple (line 9) | extern "C" fn _ffi_fn_set_empty_tuple(tuple_in_ptr: *const u8) -> i32 {
  function _ffi_fn_set_multiply_pairs (line 14) | extern "C" fn _ffi_fn_set_multiply_pairs(tuple_in_ptr: *const u8) -> f32 {
  function _ffi_fn_set_single_element_tuple (line 19) | extern "C" fn _ffi_fn_set_single_element_tuple(tuple_in_ptr: *const u8) ...
  type _ffi_rs_Rc_TupleIn (line 24) | struct _ffi_rs_Rc_TupleIn(*const u8);
  method drop (line 27) | fn drop(&mut self) {
  method empty_tuple (line 34) | fn empty_tuple(&self, x: i32, foo: (), y: i32) -> i32 {
  method single_element_tuple (line 40) | fn single_element_tuple(&self, x: (i32,), y: (i32,)) -> i32 {
  method multiply_pairs (line 45) | fn multiply_pairs(&self, ab: (f32, f32), cd: (f32, f32)) -> f32 {

FILE: src/tests/snapshots/cpp_trait_string_2021/ffi.cpp
  type _ffi_ret_ptr_2_usize (line 5) | struct _ffi_ret_ptr_2_usize {
  type _ffi_ret_ptr_usize (line 11) | struct _ffi_ret_ptr_usize {
  function _ffi_string_from_rust (line 32) | std::string _ffi_string_from_rust(const char* ptr, uintptr_t len, uintpt...
  type _ffi_Rc_Test (line 38) | struct _ffi_Rc_Test final : rust::Test {
    method _ffi_Rc_Test (line 39) | _ffi_Rc_Test(const void* ptr) : _self(ptr) {}
  function _ffi_ret_ptr_usize (line 56) | _ffi_ret_ptr_usize _ffi_cpp_Rc_Test__get_string(std::shared_ptr<rust::Te...
  function _ffi_cpp_Rc_Test__set_str (line 62) | void _ffi_cpp_Rc_Test__set_str(std::shared_ptr<rust::Test>* _self, const...
  function _ffi_cpp_Rc_Test__set_string (line 67) | void _ffi_cpp_Rc_Test__set_string(std::shared_ptr<rust::Test>* _self, co...
  function _ffi_cpp_drop_Rc_Test (line 72) | void _ffi_cpp_drop_Rc_Test(std::shared_ptr<rust::Test>* self) {

FILE: src/tests/snapshots/cpp_trait_string_2021/ffi.h
  function namespace (line 9) | namespace rust {

FILE: src/tests/snapshots/cpp_trait_string_2021/miniffi.rs
  function _ffi_Rc_Test__get_string (line 4) | extern "C" fn _ffi_Rc_Test__get_string(_self: *const u8) -> _ffi_ret_ptr...
  function _ffi_Rc_Test__set_str (line 11) | extern "C" fn _ffi_Rc_Test__set_str(_self: *const u8, x_ptr: *const u8, ...
  function _ffi_Rc_Test__set_string (line 17) | extern "C" fn _ffi_Rc_Test__set_string(_self: *const u8, x_ptr: *const u...
  function _ffi_drop_Rc_Test (line 23) | extern "C" fn _ffi_drop_Rc_Test(ptr: *const u8) {
  function _ffi_fn_get_test (line 28) | extern "C" fn _ffi_fn_get_test() -> *const u8 {
  function _ffi_fn_rust_mem_leaked (line 33) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {
  function _ffi_fn_set_test (line 38) | extern "C" fn _ffi_fn_set_test(test_ptr: *const u8) -> _ffi_ret_ptr_2_us...
  type _ffi_ret_ptr_2_usize (line 44) | struct _ffi_ret_ptr_2_usize(*const u8, usize, usize);
  type _ffi_ret_ptr_usize (line 47) | struct _ffi_ret_ptr_usize(*const u8, usize);
  type _ffi_rs_Rc_Test (line 50) | struct _ffi_rs_Rc_Test(*const u8);
  method drop (line 53) | fn drop(&mut self) {
  method get_string (line 60) | fn get_string(&self) -> String {
  method set_string (line 68) | fn set_string(&self, x: String) {
  method set_str (line 74) | fn set_str(&self, x: &str) {
  function _ffi_alloc (line 82) | extern "C" fn _ffi_alloc(len: usize) -> *const u8 {
  function _ffi_string_from_host (line 86) | fn _ffi_string_from_host(ptr: *const u8, len: usize) -> String {
  function _ffi_dealloc (line 91) | extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) {
  function _ffi_string_to_host (line 95) | fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) {

FILE: src/tests/snapshots/cpp_trait_string_2024/ffi.cpp
  type _ffi_ret_ptr_2_usize (line 5) | struct _ffi_ret_ptr_2_usize {
  type _ffi_ret_ptr_usize (line 11) | struct _ffi_ret_ptr_usize {
  function _ffi_string_from_rust (line 32) | std::string _ffi_string_from_rust(const char* ptr, uintptr_t len, uintpt...
  type _ffi_Rc_Test (line 38) | struct _ffi_Rc_Test final : rust::Test {
    method _ffi_Rc_Test (line 39) | _ffi_Rc_Test(const void* ptr) : _self(ptr) {}
  function _ffi_ret_ptr_usize (line 56) | _ffi_ret_ptr_usize _ffi_cpp_Rc_Test__get_string(std::shared_ptr<rust::Te...
  function _ffi_cpp_Rc_Test__set_str (line 62) | void _ffi_cpp_Rc_Test__set_str(std::shared_ptr<rust::Test>* _self, const...
  function _ffi_cpp_Rc_Test__set_string (line 67) | void _ffi_cpp_Rc_Test__set_string(std::shared_ptr<rust::Test>* _self, co...
  function _ffi_cpp_drop_Rc_Test (line 72) | void _ffi_cpp_drop_Rc_Test(std::shared_ptr<rust::Test>* self) {

FILE: src/tests/snapshots/cpp_trait_string_2024/ffi.h
  function namespace (line 9) | namespace rust {

FILE: src/tests/snapshots/cpp_trait_string_2024/miniffi.rs
  function _ffi_Rc_Test__get_string (line 4) | extern "C" fn _ffi_Rc_Test__get_string(_self: *const u8) -> _ffi_ret_ptr...
  function _ffi_Rc_Test__set_str (line 11) | extern "C" fn _ffi_Rc_Test__set_str(_self: *const u8, x_ptr: *const u8, ...
  function _ffi_Rc_Test__set_string (line 17) | extern "C" fn _ffi_Rc_Test__set_string(_self: *const u8, x_ptr: *const u...
  function _ffi_drop_Rc_Test (line 23) | extern "C" fn _ffi_drop_Rc_Test(ptr: *const u8) {
  function _ffi_fn_get_test (line 28) | extern "C" fn _ffi_fn_get_test() -> *const u8 {
  function _ffi_fn_rust_mem_leaked (line 33) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {
  function _ffi_fn_set_test (line 38) | extern "C" fn _ffi_fn_set_test(test_ptr: *const u8) -> _ffi_ret_ptr_2_us...
  type _ffi_ret_ptr_2_usize (line 44) | struct _ffi_ret_ptr_2_usize(*const u8, usize, usize);
  type _ffi_ret_ptr_usize (line 47) | struct _ffi_ret_ptr_usize(*const u8, usize);
  type _ffi_rs_Rc_Test (line 50) | struct _ffi_rs_Rc_Test(*const u8);
  method drop (line 53) | fn drop(&mut self) {
  method get_string (line 60) | fn get_string(&self) -> String {
  method set_string (line 68) | fn set_string(&self, x: String) {
  method set_str (line 74) | fn set_str(&self, x: &str) {
  function _ffi_alloc (line 82) | extern "C" fn _ffi_alloc(len: usize) -> *const u8 {
  function _ffi_string_from_host (line 86) | fn _ffi_string_from_host(ptr: *const u8, len: usize) -> String {
  function _ffi_dealloc (line 91) | extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) {
  function _ffi_string_to_host (line 95) | fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) {

FILE: src/tests/snapshots/swift_demo_app_2021/ffi.h
  type _ffi_ret_2_i32 (line 21) | typedef struct {
  type _ffi_ret_ptr_usize (line 26) | typedef struct {

FILE: src/tests/snapshots/swift_demo_app_2021/miniffi.rs
  function _ffi_Box_Handler__on_draw (line 4) | extern "C" fn _ffi_Box_Handler__on_draw(_self: *const u8, canvas_ptr: *c...
  function _ffi_dealloc (line 10) | extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) {
  function _ffi_buf_to_host (line 14) | fn _ffi_buf_to_host(buf: Vec<u8>) -> (*const u8, usize) {
  function _ffi_fn_create_app (line 20) | extern "C" fn _ffi_fn_create_app(platform_ptr: *const u8) {
  function _ffi_fn_rust_mem_leaked (line 25) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {
  type _ffi_ret_2_i32 (line 30) | struct _ffi_ret_2_i32(i32, i32);
  type _ffi_ret_ptr_usize (line 33) | struct _ffi_ret_ptr_usize(*const u8, usize);
  type _ffi_rs_Canvas (line 36) | struct _ffi_rs_Canvas(*const u8);
  method drop (line 39) | fn drop(&mut self) {
  method draw_text_runs (line 46) | fn draw_text_runs(&self, runs: Vec<TextRun>) {
  type _ffi_rs_Platform (line 57) | struct _ffi_rs_Platform(*const u8);
  method drop (line 60) | fn drop(&mut self) {
  method create_window (line 67) | fn create_window(&self) -> std::rc::Rc<dyn Window> {
  type _ffi_rs_Window (line 75) | struct _ffi_rs_Window(*const u8);
  method drop (line 78) | fn drop(&mut self) {
  method get_title (line 85) | fn get_title(&self) -> String {
  method set_title (line 93) | fn set_title(&self, title: &str) {
  method get_size (line 99) | fn get_size(&self) -> (i32, i32) {
  method set_size (line 107) | fn set_size(&self, width: i32, height: i32) {
  method set_handler (line 112) | fn set_handler(&self, handler: Box<dyn Handler>) {
  method child_window (line 117) | fn child_window(&self) -> std::rc::Rc<dyn Window> {
  function _ffi_rs_drop_Box_Handler (line 125) | extern "C" fn _ffi_rs_drop_Box_Handler(ptr: *const u8) {
  function _ffi_alloc (line 130) | extern "C" fn _ffi_alloc(len: usize) -> *const u8 {
  function _ffi_string_from_host (line 134) | fn _ffi_string_from_host(ptr: *const u8, len: usize) -> String {
  function _ffi_string_to_host (line 138) | fn _ffi_string_to_host(buf: String) -> (*const u8, usize, usize) {
  function _ffi_vec_TextRun_to_swift (line 144) | fn _ffi_vec_TextRun_to_swift(items: Vec<TextRun>, buf: &mut Vec<u8>) {
  function _ffi_write (line 157) | fn _ffi_write<T: Copy>(val: T, buf: &mut Vec<u8>) {

FILE: src/tests/snapshots/swift_demo_app_2024/ffi.h
  type _ffi_ret_2_i32 (line 21) | typedef struct {
  type _ffi_ret_ptr_usize (line 26) | typedef struct {

FILE: src/tests/snapshots/swift_demo_app_2024/miniffi.rs
  function _ffi_Box_Handler__on_draw (line 4) | extern "C" fn _ffi_Box_Handler__on_draw(_self: *const u8, canvas_ptr: *c...
  function _ffi_dealloc (line 10) | extern "C" fn _ffi_dealloc(ptr: *mut u8, capacity: usize) {
  function _ffi_buf_to_host (line 14) | fn _ffi_buf_to_host(buf: Vec<u8>) -> (*const u8, usize) {
  function _ffi_fn_create_app (line 20) | extern "C" fn _ffi_fn_create_app(platform_ptr: *const u8) {
  function _ffi_fn_rust_mem_leaked (line 25) | extern "C" fn _ffi_fn_rust_mem_leaked() -> usize {
  type _ffi_ret_2_i32 (line 30) | struct _ffi_ret_2_i32(i32, i32);
  type _ffi_ret_ptr_usize (line 33) | struct _ffi_ret_ptr_usize(*const u8, usize);
  type _ffi_rs_Canvas (line 36) | struct _ffi_rs_Canvas(*const u8);
  method drop (line 39) | fn drop(&mut self) {
  method draw_text_runs (line 46) | fn draw_text_runs(&self, runs: Vec<TextRun>) {
  type _ffi_rs_Platform (line 57) | struct _ffi_rs_Platform(*const u8);
  method drop (line 60) | fn drop(&mut self) {
  met
Condensed preview — 815 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (2,669K chars).
[
  {
    "path": "Cargo.toml",
    "chars": 384,
    "preview": "[package]\nname = \"miniffi\"\nversion = \"0.1.0\"\nedition = \"2021\"\nlicense = \"MIT\"\nrepository = \"https://github.com/evanw/min"
  },
  {
    "path": "LICENSE.md",
    "chars": 1052,
    "preview": "Copyright 2025 Evan Wallace\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this softwa"
  },
  {
    "path": "README.md",
    "chars": 3675,
    "preview": "# miniffi\n\n> [!WARNING]\n> This project is on its first release. I'm still trying out the idea. It has\n> not been used in"
  },
  {
    "path": "src/ast.rs",
    "chars": 5691,
    "preview": "use super::*;\nuse std::collections::HashSet;\nuse std::fmt::Write;\n\npub struct AST {\n    pub structs: Vec<RustStruct>,\n  "
  },
  {
    "path": "src/cpp.rs",
    "chars": 116531,
    "preview": "use super::*;\nuse std::borrow::Cow;\nuse std::collections::{HashMap, HashSet};\nuse std::hash::Hash;\nuse std::rc::Rc;\n\n///"
  },
  {
    "path": "src/lib.rs",
    "chars": 17276,
    "preview": "//! This is a simple but opinionated FFI system for Rust. It allows you to call\n//! Rust code from other languages, and "
  },
  {
    "path": "src/rust.rs",
    "chars": 9615,
    "preview": "use super::*;\nuse std::borrow::Cow;\n\n#[derive(Default)]\npub struct RustSyntax {\n    edition: usize,\n}\n\nimpl RustSyntax {"
  },
  {
    "path": "src/scan.rs",
    "chars": 23730,
    "preview": "use super::*;\nuse std::collections::HashSet;\nuse syn::{Attribute, Fields, ext::IdentExt};\n\npub fn scan_ast(file: &FileDa"
  },
  {
    "path": "src/swift.rs",
    "chars": 94365,
    "preview": "use super::*;\nuse std::borrow::Cow;\nuse std::collections::{HashMap, HashSet};\nuse std::rc::Rc;\n\n/// Use this target when"
  },
  {
    "path": "src/tests/cases/demo_app.rs",
    "chars": 2227,
    "preview": "use super::*;\n\nfn test_case() -> TestCase {\n    let mut case = TestCase::default();\n\n    case.rust = r#\"\n        use std"
  },
  {
    "path": "src/tests/cases/demo_const.rs",
    "chars": 3227,
    "preview": "use super::*;\n\nfn test_case() -> TestCase {\n    let mut case = TestCase::default();\n\n    case.rust = r#\"\n        pub con"
  },
  {
    "path": "src/tests/cases/demo_derive_eq.rs",
    "chars": 46361,
    "preview": "use super::*;\n\nfn test_case() -> TestCase {\n    let mut case = TestCase::default();\n\n    case.rust = r#\"\n        #[deriv"
  },
  {
    "path": "src/tests/cases/demo_enum.rs",
    "chars": 935,
    "preview": "use super::*;\n\nfn test_case() -> TestCase {\n    let mut case = TestCase::default();\n\n    case.rust = r#\"\n        // This"
  },
  {
    "path": "src/tests/cases/demo_keyword.rs",
    "chars": 1626,
    "preview": "use super::*;\nuse std::collections::HashSet;\n\nconst RUST_KEYWORDS: &[&str] = &[\n    \"abstract\", \"as\", \"async\", \"await\", "
  },
  {
    "path": "src/tests/cases/demo_order.rs",
    "chars": 1740,
    "preview": "use super::*;\n\nfn test_case() -> TestCase {\n    let mut case = TestCase::default();\n\n    case.rust = r#\"\n        use std"
  },
  {
    "path": "src/tests/cases/demo_trait.rs",
    "chars": 6198,
    "preview": "use super::*;\n\nfn test_case() -> TestCase {\n    let mut case = TestCase::default();\n\n    case.rust = r#\"\n        use std"
  },
  {
    "path": "src/tests/cases/fn_basic.rs",
    "chars": 3159,
    "preview": "use super::*;\n\nfn test_case() -> TestCase {\n    let mut case = TestCase::default();\n\n    case.rust = r#\"\n        pub fn "
  },
  {
    "path": "src/tests/cases/fn_basic_void.rs",
    "chars": 1286,
    "preview": "use super::*;\n\nfn test_case() -> TestCase {\n    let mut case = TestCase::default();\n\n    case.rust = r#\"\n        static "
  },
  {
    "path": "src/tests/cases/fn_box_in.rs",
    "chars": 6992,
    "preview": "use super::*;\n\nfn test_case() -> TestCase {\n    let mut case = TestCase::default();\n\n    case.rust = r#\"\n        #[deriv"
  },
  {
    "path": "src/tests/cases/fn_box_out.rs",
    "chars": 7552,
    "preview": "use super::*;\n\nfn test_case() -> TestCase {\n    let mut case = TestCase::default();\n\n    case.rust = r#\"\n        #[deriv"
  },
  {
    "path": "src/tests/cases/fn_combo_in.rs",
    "chars": 3462,
    "preview": "use super::*;\n\nfn test_case() -> TestCase {\n    let mut case = TestCase::default();\n\n    case.rust = r#\"\n        #[deriv"
  },
  {
    "path": "src/tests/cases/fn_combo_out.rs",
    "chars": 3830,
    "preview": "use super::*;\n\nfn test_case() -> TestCase {\n    let mut case = TestCase::default();\n\n    case.rust = r#\"\n        #[deriv"
  },
  {
    "path": "src/tests/cases/fn_enum_in.rs",
    "chars": 1623,
    "preview": "use super::*;\n\nfn test_case() -> TestCase {\n    let mut case = TestCase::default();\n\n    case.rust = r#\"\n        pub enu"
  },
  {
    "path": "src/tests/cases/fn_enum_out.rs",
    "chars": 1891,
    "preview": "use super::*;\n\nfn test_case() -> TestCase {\n    let mut case = TestCase::default();\n\n    case.rust = r#\"\n        pub enu"
  },
  {
    "path": "src/tests/cases/fn_nested_in.rs",
    "chars": 4457,
    "preview": "use super::*;\n\nfn test_case() -> TestCase {\n    let mut case = TestCase::default();\n\n    case.rust = r#\"\n        use std"
  },
  {
    "path": "src/tests/cases/fn_nested_out.rs",
    "chars": 1101,
    "preview": "use super::*;\n\nfn test_case() -> TestCase {\n    let mut case = TestCase::default();\n\n    case.rust = r#\"\n        use std"
  },
  {
    "path": "src/tests/cases/fn_option_in.rs",
    "chars": 4203,
    "preview": "use super::*;\n\nfn test_case() -> TestCase {\n    let mut case = TestCase::default();\n\n    case.rust = r#\"\n        pub fn "
  },
  {
    "path": "src/tests/cases/fn_option_out.rs",
    "chars": 3316,
    "preview": "use super::*;\n\nfn test_case() -> TestCase {\n    let mut case = TestCase::default();\n\n    case.rust = r#\"\n        pub fn "
  },
  {
    "path": "src/tests/cases/fn_payload_in.rs",
    "chars": 2244,
    "preview": "use super::*;\n\nfn test_case() -> TestCase {\n    let mut case = TestCase::default();\n\n    case.rust = r#\"\n        #[deriv"
  },
  {
    "path": "src/tests/cases/fn_payload_out.rs",
    "chars": 1979,
    "preview": "use super::*;\n\nfn test_case() -> TestCase {\n    let mut case = TestCase::default();\n\n    case.rust = r#\"\n        #[deriv"
  },
  {
    "path": "src/tests/cases/fn_string.rs",
    "chars": 2437,
    "preview": "use super::*;\n\nfn test_case() -> TestCase {\n    let mut case = TestCase::default();\n\n    case.rust = r#\"\n        use std"
  },
  {
    "path": "src/tests/cases/fn_struct_in.rs",
    "chars": 1756,
    "preview": "use super::*;\n\nfn test_case() -> TestCase {\n    let mut case = TestCase::default();\n\n    case.rust = r#\"\n        pub str"
  },
  {
    "path": "src/tests/cases/fn_struct_out.rs",
    "chars": 1224,
    "preview": "use super::*;\n\nfn test_case() -> TestCase {\n    let mut case = TestCase::default();\n\n    case.rust = r#\"\n        #[deriv"
  },
  {
    "path": "src/tests/cases/fn_tuple_in.rs",
    "chars": 1892,
    "preview": "use super::*;\n\nfn test_case() -> TestCase {\n    let mut case = TestCase::default();\n\n    case.rust = r#\"\n        pub fn "
  },
  {
    "path": "src/tests/cases/fn_tuple_out.rs",
    "chars": 687,
    "preview": "use super::*;\n\nfn test_case() -> TestCase {\n    let mut case = TestCase::default();\n\n    case.rust = r#\"\n        pub fn "
  },
  {
    "path": "src/tests/cases/fn_vec_in.rs",
    "chars": 7619,
    "preview": "use super::*;\n\nfn test_case() -> TestCase {\n    let mut case = TestCase::default();\n\n    case.rust = r#\"\n        pub fn "
  },
  {
    "path": "src/tests/cases/fn_vec_out.rs",
    "chars": 1795,
    "preview": "use super::*;\n\nfn test_case() -> TestCase {\n    let mut case = TestCase::default();\n\n    case.rust = r#\"\n        pub fn "
  },
  {
    "path": "src/tests/cases/mod.rs",
    "chars": 720,
    "preview": "use super::*;\n\nmod demo_app;\nmod demo_const;\nmod demo_derive_eq;\nmod demo_enum;\nmod demo_keyword;\nmod demo_order;\nmod de"
  },
  {
    "path": "src/tests/cases/trait_enum.rs",
    "chars": 1132,
    "preview": "use super::*;\n\nfn test_case() -> TestCase {\n    let mut case = TestCase::default();\n\n    case.rust = r#\"\n        pub tra"
  },
  {
    "path": "src/tests/cases/trait_export.rs",
    "chars": 1851,
    "preview": "use super::*;\n\nfn test_case() -> TestCase {\n    let mut case = TestCase::default();\n\n    case.rust = r#\"\n        use std"
  },
  {
    "path": "src/tests/cases/trait_export_import.rs",
    "chars": 2413,
    "preview": "use super::*;\n\nfn test_case() -> TestCase {\n    let mut case = TestCase::default();\n\n    case.rust = r#\"\n        use std"
  },
  {
    "path": "src/tests/cases/trait_export_nested.rs",
    "chars": 2223,
    "preview": "use super::*;\n\nfn test_case() -> TestCase {\n    let mut case = TestCase::default();\n\n    case.rust = r#\"\n        use std"
  },
  {
    "path": "src/tests/cases/trait_import.rs",
    "chars": 2070,
    "preview": "use super::*;\n\nfn test_case() -> TestCase {\n    let mut case = TestCase::default();\n\n    case.rust = r#\"\n        use std"
  },
  {
    "path": "src/tests/cases/trait_import_export.rs",
    "chars": 2425,
    "preview": "use super::*;\n\nfn test_case() -> TestCase {\n    let mut case = TestCase::default();\n\n    case.rust = r#\"\n        use std"
  },
  {
    "path": "src/tests/cases/trait_import_nested.rs",
    "chars": 2564,
    "preview": "use super::*;\n\nfn test_case() -> TestCase {\n    let mut case = TestCase::default();\n\n    case.rust = r#\"\n        use std"
  },
  {
    "path": "src/tests/cases/trait_import_struct_in.rs",
    "chars": 3283,
    "preview": "use super::*;\n\nfn test_case() -> TestCase {\n    let mut case = TestCase::default();\n\n    case.rust = r#\"\n        use std"
  },
  {
    "path": "src/tests/cases/trait_import_tuple_in.rs",
    "chars": 3117,
    "preview": "use super::*;\n\nfn test_case() -> TestCase {\n    let mut case = TestCase::default();\n\n    case.rust = r#\"\n        use std"
  },
  {
    "path": "src/tests/cases/trait_string.rs",
    "chars": 4046,
    "preview": "use super::*;\n\nfn test_case() -> TestCase {\n    let mut case = TestCase::default();\n\n    case.rust = r#\"\n        use std"
  },
  {
    "path": "src/tests/cpp.rs",
    "chars": 12287,
    "preview": "use super::*;\n\npub fn run_test(name: &str, case: &TestCase, edition: usize) {\n    let name = Path::new(name).file_stem()"
  },
  {
    "path": "src/tests/mod.rs",
    "chars": 7523,
    "preview": "use super::*;\nuse std::process::{Command, Output};\nuse std::sync::{Mutex, OnceLock};\n\nmod cases;\nmod cpp;\nmod swift;\nmod"
  },
  {
    "path": "src/tests/snapshots/cpp_demo_app_2021/ffi.cpp",
    "chars": 4608,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#include \"ffi.h\"\n\nstruct _ffi_ret_2_i32 {\n    int32_t _0;\n  "
  },
  {
    "path": "src/tests/snapshots/cpp_demo_app_2021/ffi.h",
    "chars": 1215,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#pragma once\n\n#include <memory>\n#include <stdint.h>\n#include"
  },
  {
    "path": "src/tests/snapshots/cpp_demo_app_2021/miniffi.rs",
    "chars": 5579,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#[no_mangle]\nextern \"C\" fn _ffi_Box_Handler__on_draw(_self: "
  },
  {
    "path": "src/tests/snapshots/cpp_demo_app_2024/ffi.cpp",
    "chars": 4608,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#include \"ffi.h\"\n\nstruct _ffi_ret_2_i32 {\n    int32_t _0;\n  "
  },
  {
    "path": "src/tests/snapshots/cpp_demo_app_2024/ffi.h",
    "chars": 1215,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#pragma once\n\n#include <memory>\n#include <stdint.h>\n#include"
  },
  {
    "path": "src/tests/snapshots/cpp_demo_app_2024/miniffi.rs",
    "chars": 5704,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#[unsafe(no_mangle)]\nextern \"C\" fn _ffi_Box_Handler__on_draw"
  },
  {
    "path": "src/tests/snapshots/cpp_demo_const_2021/ffi.cpp",
    "chars": 223,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#include \"ffi.h\"\n\nextern \"C\" {\n\nuintptr_t _ffi_fn_rust_mem_l"
  },
  {
    "path": "src/tests/snapshots/cpp_demo_const_2021/ffi.h",
    "chars": 1138,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#pragma once\n\n#include <stdint.h>\n#include <string_view>\n\nna"
  },
  {
    "path": "src/tests/snapshots/cpp_demo_const_2021/miniffi.rs",
    "chars": 148,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#[no_mangle]\nextern \"C\" fn _ffi_fn_rust_mem_leaked() -> usiz"
  },
  {
    "path": "src/tests/snapshots/cpp_demo_const_2024/ffi.cpp",
    "chars": 223,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#include \"ffi.h\"\n\nextern \"C\" {\n\nuintptr_t _ffi_fn_rust_mem_l"
  },
  {
    "path": "src/tests/snapshots/cpp_demo_const_2024/ffi.h",
    "chars": 1138,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#pragma once\n\n#include <stdint.h>\n#include <string_view>\n\nna"
  },
  {
    "path": "src/tests/snapshots/cpp_demo_const_2024/miniffi.rs",
    "chars": 156,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#[unsafe(no_mangle)]\nextern \"C\" fn _ffi_fn_rust_mem_leaked()"
  },
  {
    "path": "src/tests/snapshots/cpp_demo_derive_eq_2021/ffi.cpp",
    "chars": 28099,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#include \"ffi.h\"\n#include <stdlib.h>\n#include <algorithm>\n\ns"
  },
  {
    "path": "src/tests/snapshots/cpp_demo_derive_eq_2021/ffi.h",
    "chars": 8144,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#pragma once\n\n#include <stdint.h>\n#include <tuple>\n#include "
  },
  {
    "path": "src/tests/snapshots/cpp_demo_derive_eq_2021/miniffi.rs",
    "chars": 18988,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#[allow(non_snake_case)]\nfn _ffi_box__from_cpp(_: &mut *cons"
  },
  {
    "path": "src/tests/snapshots/cpp_demo_derive_eq_2024/ffi.cpp",
    "chars": 28099,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#include \"ffi.h\"\n#include <stdlib.h>\n#include <algorithm>\n\ns"
  },
  {
    "path": "src/tests/snapshots/cpp_demo_derive_eq_2024/ffi.h",
    "chars": 8144,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#pragma once\n\n#include <stdint.h>\n#include <tuple>\n#include "
  },
  {
    "path": "src/tests/snapshots/cpp_demo_derive_eq_2024/miniffi.rs",
    "chars": 19196,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#[allow(non_snake_case)]\nfn _ffi_box__from_cpp(_: &mut *cons"
  },
  {
    "path": "src/tests/snapshots/cpp_demo_enum_2021/ffi.cpp",
    "chars": 223,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#include \"ffi.h\"\n\nextern \"C\" {\n\nuintptr_t _ffi_fn_rust_mem_l"
  },
  {
    "path": "src/tests/snapshots/cpp_demo_enum_2021/ffi.h",
    "chars": 4724,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#pragma once\n\n#include <stdint.h>\n#include <variant>\n#includ"
  },
  {
    "path": "src/tests/snapshots/cpp_demo_enum_2021/miniffi.rs",
    "chars": 148,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#[no_mangle]\nextern \"C\" fn _ffi_fn_rust_mem_leaked() -> usiz"
  },
  {
    "path": "src/tests/snapshots/cpp_demo_enum_2024/ffi.cpp",
    "chars": 223,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#include \"ffi.h\"\n\nextern \"C\" {\n\nuintptr_t _ffi_fn_rust_mem_l"
  },
  {
    "path": "src/tests/snapshots/cpp_demo_enum_2024/ffi.h",
    "chars": 4724,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#pragma once\n\n#include <stdint.h>\n#include <variant>\n#includ"
  },
  {
    "path": "src/tests/snapshots/cpp_demo_enum_2024/miniffi.rs",
    "chars": 156,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#[unsafe(no_mangle)]\nextern \"C\" fn _ffi_fn_rust_mem_leaked()"
  },
  {
    "path": "src/tests/snapshots/cpp_demo_keyword_2021/ffi.cpp",
    "chars": 20260,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#include \"ffi.h\"\n\nextern \"C\" {\n\nuintptr_t _ffi_fn_rust_mem_l"
  },
  {
    "path": "src/tests/snapshots/cpp_demo_keyword_2021/ffi.h",
    "chars": 5984,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#pragma once\n\n#include <stdint.h>\n\nnamespace rust {\n\nuintptr"
  },
  {
    "path": "src/tests/snapshots/cpp_demo_keyword_2021/miniffi.rs",
    "chars": 14650,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#[no_mangle]\nextern \"C\" fn _ffi_fn_rust_mem_leaked() -> usiz"
  },
  {
    "path": "src/tests/snapshots/cpp_demo_keyword_2024/ffi.cpp",
    "chars": 20260,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#include \"ffi.h\"\n\nextern \"C\" {\n\nuintptr_t _ffi_fn_rust_mem_l"
  },
  {
    "path": "src/tests/snapshots/cpp_demo_keyword_2024/ffi.h",
    "chars": 5984,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#pragma once\n\n#include <stdint.h>\n\nnamespace rust {\n\nuintptr"
  },
  {
    "path": "src/tests/snapshots/cpp_demo_keyword_2024/miniffi.rs",
    "chars": 15802,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#[unsafe(no_mangle)]\nextern \"C\" fn _ffi_fn_rust_mem_leaked()"
  },
  {
    "path": "src/tests/snapshots/cpp_demo_order_2021/ffi.cpp",
    "chars": 223,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#include \"ffi.h\"\n\nextern \"C\" {\n\nuintptr_t _ffi_fn_rust_mem_l"
  },
  {
    "path": "src/tests/snapshots/cpp_demo_order_2021/ffi.h",
    "chars": 4093,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#pragma once\n\n#include <stdint.h>\n#include <variant>\n#includ"
  },
  {
    "path": "src/tests/snapshots/cpp_demo_order_2021/miniffi.rs",
    "chars": 148,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#[no_mangle]\nextern \"C\" fn _ffi_fn_rust_mem_leaked() -> usiz"
  },
  {
    "path": "src/tests/snapshots/cpp_demo_order_2024/ffi.cpp",
    "chars": 223,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#include \"ffi.h\"\n\nextern \"C\" {\n\nuintptr_t _ffi_fn_rust_mem_l"
  },
  {
    "path": "src/tests/snapshots/cpp_demo_order_2024/ffi.h",
    "chars": 4093,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#pragma once\n\n#include <stdint.h>\n#include <variant>\n#includ"
  },
  {
    "path": "src/tests/snapshots/cpp_demo_order_2024/miniffi.rs",
    "chars": 156,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#[unsafe(no_mangle)]\nextern \"C\" fn _ffi_fn_rust_mem_leaked()"
  },
  {
    "path": "src/tests/snapshots/cpp_demo_trait_2021/ffi.cpp",
    "chars": 6447,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#include \"ffi.h\"\n\nstruct _ffi_ret_ptr_2_usize {\n    const vo"
  },
  {
    "path": "src/tests/snapshots/cpp_demo_trait_2021/ffi.h",
    "chars": 571,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#pragma once\n\n#include <stdint.h>\n#include <vector>\n#include"
  },
  {
    "path": "src/tests/snapshots/cpp_demo_trait_2021/miniffi.rs",
    "chars": 5904,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#[no_mangle]\nextern \"C\" fn _ffi_Box_Trait__get(_self: *const"
  },
  {
    "path": "src/tests/snapshots/cpp_demo_trait_2024/ffi.cpp",
    "chars": 6447,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#include \"ffi.h\"\n\nstruct _ffi_ret_ptr_2_usize {\n    const vo"
  },
  {
    "path": "src/tests/snapshots/cpp_demo_trait_2024/ffi.h",
    "chars": 571,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#pragma once\n\n#include <stdint.h>\n#include <vector>\n#include"
  },
  {
    "path": "src/tests/snapshots/cpp_demo_trait_2024/miniffi.rs",
    "chars": 5996,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#[unsafe(no_mangle)]\nextern \"C\" fn _ffi_Box_Trait__get(_self"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_basic_2021/ffi.cpp",
    "chars": 1916,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#include \"ffi.h\"\n\nextern \"C\" {\n\nbool _ffi_fn_add_bool(bool x"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_basic_2021/ffi.h",
    "chars": 683,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#pragma once\n\n#include <stdint.h>\n\nnamespace rust {\n\nuintptr"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_basic_2021/miniffi.rs",
    "chars": 1320,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#[no_mangle]\nextern \"C\" fn _ffi_fn_add_bool(x: bool, y: bool"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_basic_2024/ffi.cpp",
    "chars": 1916,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#include \"ffi.h\"\n\nextern \"C\" {\n\nbool _ffi_fn_add_bool(bool x"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_basic_2024/ffi.h",
    "chars": 683,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#pragma once\n\n#include <stdint.h>\n\nnamespace rust {\n\nuintptr"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_basic_2024/miniffi.rs",
    "chars": 1432,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#[unsafe(no_mangle)]\nextern \"C\" fn _ffi_fn_add_bool(x: bool,"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_basic_void_2021/ffi.cpp",
    "chars": 806,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#include \"ffi.h\"\n\nextern \"C\" {\n\nvoid _ffi_fn_add_empty_tuple"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_basic_void_2021/ffi.h",
    "chars": 359,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#pragma once\n\n#include <stdint.h>\n#include <tuple>\n\nnamespac"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_basic_void_2021/miniffi.rs",
    "chars": 510,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#[no_mangle]\nextern \"C\" fn _ffi_fn_add_empty_tuple(x: i32, y"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_basic_void_2024/ffi.cpp",
    "chars": 806,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#include \"ffi.h\"\n\nextern \"C\" {\n\nvoid _ffi_fn_add_empty_tuple"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_basic_void_2024/ffi.h",
    "chars": 359,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#pragma once\n\n#include <stdint.h>\n#include <tuple>\n\nnamespac"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_basic_void_2024/miniffi.rs",
    "chars": 550,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#[unsafe(no_mangle)]\nextern \"C\" fn _ffi_fn_add_empty_tuple(x"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_box_in_2021/ffi.cpp",
    "chars": 2701,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#include \"ffi.h\"\n#include <vector>\n\nextern \"C\" {\n\nint32_t _f"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_box_in_2021/ffi.h",
    "chars": 577,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#pragma once\n\n#include <memory>\n#include <stdint.h>\n#include"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_box_in_2021/miniffi.rs",
    "chars": 1982,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#[allow(non_snake_case)]\nfn _ffi_box_Tree_from_cpp(end: &mut"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_box_in_2024/ffi.cpp",
    "chars": 2701,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#include \"ffi.h\"\n#include <vector>\n\nextern \"C\" {\n\nint32_t _f"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_box_in_2024/ffi.h",
    "chars": 577,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#pragma once\n\n#include <memory>\n#include <stdint.h>\n#include"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_box_in_2024/miniffi.rs",
    "chars": 2014,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#[allow(non_snake_case)]\nfn _ffi_box_Tree_from_cpp(end: &mut"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_box_out_2021/ffi.cpp",
    "chars": 3263,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#include \"ffi.h\"\n\nstruct _ffi_ret_i32_ptr_usize_2_bool {\n   "
  },
  {
    "path": "src/tests/snapshots/cpp_fn_box_out_2021/ffi.h",
    "chars": 715,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#pragma once\n\n#include <stdint.h>\n#include <memory>\n#include"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_box_out_2021/miniffi.rs",
    "chars": 2490,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#[allow(non_snake_case)]\nfn _ffi_box_Tree_to_cpp(val: Tree, "
  },
  {
    "path": "src/tests/snapshots/cpp_fn_box_out_2024/ffi.cpp",
    "chars": 3263,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#include \"ffi.h\"\n\nstruct _ffi_ret_i32_ptr_usize_2_bool {\n   "
  },
  {
    "path": "src/tests/snapshots/cpp_fn_box_out_2024/ffi.h",
    "chars": 715,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#pragma once\n\n#include <stdint.h>\n#include <memory>\n#include"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_box_out_2024/miniffi.rs",
    "chars": 2522,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#[allow(non_snake_case)]\nfn _ffi_box_Tree_to_cpp(val: Tree, "
  },
  {
    "path": "src/tests/snapshots/cpp_fn_combo_in_2021/ffi.cpp",
    "chars": 3275,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#include \"ffi.h\"\n\nstruct _ffi_ret_ptr_2_usize {\n    const ch"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_combo_in_2021/ffi.h",
    "chars": 485,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#pragma once\n\n#include <stdint.h>\n#include <string>\n#include"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_combo_in_2021/miniffi.rs",
    "chars": 2830,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#[no_mangle]\nextern \"C\" fn _ffi_alloc(len: usize) -> *const "
  },
  {
    "path": "src/tests/snapshots/cpp_fn_combo_in_2024/ffi.cpp",
    "chars": 3275,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#include \"ffi.h\"\n\nstruct _ffi_ret_ptr_2_usize {\n    const ch"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_combo_in_2024/ffi.h",
    "chars": 485,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#pragma once\n\n#include <stdint.h>\n#include <string>\n#include"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_combo_in_2024/miniffi.rs",
    "chars": 2862,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#[unsafe(no_mangle)]\nextern \"C\" fn _ffi_alloc(len: usize) ->"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_combo_out_2021/ffi.cpp",
    "chars": 4741,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#include \"ffi.h\"\n\nstruct _ffi_ret_i32_ptr_4_usize {\n    int3"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_combo_out_2021/ffi.h",
    "chars": 692,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#pragma once\n\n#include <stdint.h>\n#include <vector>\n#include"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_combo_out_2021/miniffi.rs",
    "chars": 3096,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#[no_mangle]\nextern \"C\" fn _ffi_dealloc(ptr: *mut u8, capaci"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_combo_out_2024/ffi.cpp",
    "chars": 4741,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#include \"ffi.h\"\n\nstruct _ffi_ret_i32_ptr_4_usize {\n    int3"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_combo_out_2024/ffi.h",
    "chars": 692,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#pragma once\n\n#include <stdint.h>\n#include <vector>\n#include"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_combo_out_2024/miniffi.rs",
    "chars": 3128,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#[unsafe(no_mangle)]\nextern \"C\" fn _ffi_dealloc(ptr: *mut u8"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_enum_in_2021/ffi.cpp",
    "chars": 2256,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#include \"ffi.h\"\n#include <stdlib.h>\n#include <vector>\n\nexte"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_enum_in_2021/ffi.h",
    "chars": 1743,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#pragma once\n\n#include <stdint.h>\n#include <variant>\n\nnamesp"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_enum_in_2021/miniffi.rs",
    "chars": 2394,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#[no_mangle]\nextern \"C\" fn _ffi_alloc(len: usize) -> *const "
  },
  {
    "path": "src/tests/snapshots/cpp_fn_enum_in_2024/ffi.cpp",
    "chars": 2256,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#include \"ffi.h\"\n#include <stdlib.h>\n#include <vector>\n\nexte"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_enum_in_2024/ffi.h",
    "chars": 1743,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#pragma once\n\n#include <stdint.h>\n#include <variant>\n\nnamesp"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_enum_in_2024/miniffi.rs",
    "chars": 2434,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#[unsafe(no_mangle)]\nextern \"C\" fn _ffi_alloc(len: usize) ->"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_enum_out_2021/ffi.cpp",
    "chars": 2461,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#include \"ffi.h\"\n#include <stdlib.h>\n\nstruct _ffi_ret_ptr_us"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_enum_out_2021/ffi.h",
    "chars": 1737,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#pragma once\n\n#include <stdint.h>\n#include <variant>\n\nnamesp"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_enum_out_2021/miniffi.rs",
    "chars": 2236,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#[no_mangle]\nextern \"C\" fn _ffi_dealloc(ptr: *mut u8, capaci"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_enum_out_2024/ffi.cpp",
    "chars": 2461,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#include \"ffi.h\"\n#include <stdlib.h>\n\nstruct _ffi_ret_ptr_us"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_enum_out_2024/ffi.h",
    "chars": 1737,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#pragma once\n\n#include <stdint.h>\n#include <variant>\n\nnamesp"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_enum_out_2024/miniffi.rs",
    "chars": 2276,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#[unsafe(no_mangle)]\nextern \"C\" fn _ffi_dealloc(ptr: *mut u8"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_nested_in_2021/ffi.cpp",
    "chars": 1713,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#include \"ffi.h\"\n\nextern \"C\" {\n\nuintptr_t _ffi_fn_rust_mem_l"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_nested_in_2021/ffi.h",
    "chars": 452,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#pragma once\n\n#include <stdint.h>\n#include <tuple>\n#include "
  },
  {
    "path": "src/tests/snapshots/cpp_fn_nested_in_2021/miniffi.rs",
    "chars": 1841,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#[no_mangle]\nextern \"C\" fn _ffi_alloc(len: usize) -> *const "
  },
  {
    "path": "src/tests/snapshots/cpp_fn_nested_in_2024/ffi.cpp",
    "chars": 1713,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#include \"ffi.h\"\n\nextern \"C\" {\n\nuintptr_t _ffi_fn_rust_mem_l"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_nested_in_2024/ffi.h",
    "chars": 452,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#pragma once\n\n#include <stdint.h>\n#include <tuple>\n#include "
  },
  {
    "path": "src/tests/snapshots/cpp_fn_nested_in_2024/miniffi.rs",
    "chars": 1879,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#[unsafe(no_mangle)]\nextern \"C\" fn _ffi_alloc(len: usize) ->"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_nested_out_2021/ffi.cpp",
    "chars": 1047,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#include \"ffi.h\"\n\nstruct _ffi_ret_i32_ptr {\n    int32_t _0;\n"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_nested_out_2021/ffi.h",
    "chars": 371,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#pragma once\n\n#include <stdint.h>\n#include <tuple>\n#include "
  },
  {
    "path": "src/tests/snapshots/cpp_fn_nested_out_2021/miniffi.rs",
    "chars": 714,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#[no_mangle]\nextern \"C\" fn _ffi_Rc_Bar__get(_self: *const u8"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_nested_out_2024/ffi.cpp",
    "chars": 1047,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#include \"ffi.h\"\n\nstruct _ffi_ret_i32_ptr {\n    int32_t _0;\n"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_nested_out_2024/ffi.h",
    "chars": 371,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#pragma once\n\n#include <stdint.h>\n#include <tuple>\n#include "
  },
  {
    "path": "src/tests/snapshots/cpp_fn_nested_out_2024/miniffi.rs",
    "chars": 746,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#[unsafe(no_mangle)]\nextern \"C\" fn _ffi_Rc_Bar__get(_self: *"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_option_in_2021/ffi.cpp",
    "chars": 3879,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#include \"ffi.h\"\n\nstruct _ffi_ret_ptr_2_usize {\n    const ch"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_option_in_2021/ffi.h",
    "chars": 518,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#pragma once\n\n#include <optional>\n#include <stdint.h>\n#inclu"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_option_in_2021/miniffi.rs",
    "chars": 3085,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#[no_mangle]\nextern \"C\" fn _ffi_alloc(len: usize) -> *const "
  },
  {
    "path": "src/tests/snapshots/cpp_fn_option_in_2024/ffi.cpp",
    "chars": 3879,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#include \"ffi.h\"\n\nstruct _ffi_ret_ptr_2_usize {\n    const ch"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_option_in_2024/ffi.h",
    "chars": 518,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#pragma once\n\n#include <optional>\n#include <stdint.h>\n#inclu"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_option_in_2024/miniffi.rs",
    "chars": 3141,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#[unsafe(no_mangle)]\nextern \"C\" fn _ffi_alloc(len: usize) ->"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_option_out_2021/ffi.cpp",
    "chars": 3910,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#include \"ffi.h\"\n\nstruct _ffi_ret_ptr_2_usize {\n    const vo"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_option_out_2021/ffi.h",
    "chars": 498,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#pragma once\n\n#include <optional>\n#include <stdint.h>\n#inclu"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_option_out_2021/miniffi.rs",
    "chars": 3287,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#[no_mangle]\nextern \"C\" fn _ffi_dealloc(ptr: *mut u8, capaci"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_option_out_2024/ffi.cpp",
    "chars": 3910,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#include \"ffi.h\"\n\nstruct _ffi_ret_ptr_2_usize {\n    const vo"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_option_out_2024/ffi.h",
    "chars": 498,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#pragma once\n\n#include <optional>\n#include <stdint.h>\n#inclu"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_option_out_2024/miniffi.rs",
    "chars": 3335,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#[unsafe(no_mangle)]\nextern \"C\" fn _ffi_dealloc(ptr: *mut u8"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_payload_in_2021/ffi.cpp",
    "chars": 2270,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#include \"ffi.h\"\n#include <stdlib.h>\n\nextern \"C\" {\n\nuintptr_"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_payload_in_2021/ffi.h",
    "chars": 1613,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#pragma once\n\n#include <stdint.h>\n#include <vector>\n#include"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_payload_in_2021/miniffi.rs",
    "chars": 1646,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#[allow(non_snake_case)]\nfn _ffi_box_Foo_from_cpp(end: &mut "
  },
  {
    "path": "src/tests/snapshots/cpp_fn_payload_in_2024/ffi.cpp",
    "chars": 2270,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#include \"ffi.h\"\n#include <stdlib.h>\n\nextern \"C\" {\n\nuintptr_"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_payload_in_2024/ffi.h",
    "chars": 1613,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#pragma once\n\n#include <stdint.h>\n#include <vector>\n#include"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_payload_in_2024/miniffi.rs",
    "chars": 1670,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#[allow(non_snake_case)]\nfn _ffi_box_Foo_from_cpp(end: &mut "
  },
  {
    "path": "src/tests/snapshots/cpp_fn_payload_out_2021/ffi.cpp",
    "chars": 2411,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#include \"ffi.h\"\n#include <stdlib.h>\n\nstruct _ffi_ret_ptr_2_"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_payload_out_2021/ffi.h",
    "chars": 1603,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#pragma once\n\n#include <stdint.h>\n#include <vector>\n#include"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_payload_out_2021/miniffi.rs",
    "chars": 1835,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#[allow(non_snake_case)]\nfn _ffi_box_Foo_to_cpp(val: Foo, bu"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_payload_out_2024/ffi.cpp",
    "chars": 2411,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#include \"ffi.h\"\n#include <stdlib.h>\n\nstruct _ffi_ret_ptr_2_"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_payload_out_2024/ffi.h",
    "chars": 1603,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#pragma once\n\n#include <stdint.h>\n#include <vector>\n#include"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_payload_out_2024/miniffi.rs",
    "chars": 1859,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#[allow(non_snake_case)]\nfn _ffi_box_Foo_to_cpp(val: Foo, bu"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_string_2021/ffi.cpp",
    "chars": 1625,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#include \"ffi.h\"\n\nstruct _ffi_ret_ptr_2_usize {\n    const ch"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_string_2021/ffi.h",
    "chars": 313,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#pragma once\n\n#include <stdint.h>\n#include <string>\n\nnamespa"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_string_2021/miniffi.rs",
    "chars": 1415,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#[no_mangle]\nextern \"C\" fn _ffi_fn_get_string() -> _ffi_ret_"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_string_2024/ffi.cpp",
    "chars": 1625,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#include \"ffi.h\"\n\nstruct _ffi_ret_ptr_2_usize {\n    const ch"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_string_2024/ffi.h",
    "chars": 313,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#pragma once\n\n#include <stdint.h>\n#include <string>\n\nnamespa"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_string_2024/miniffi.rs",
    "chars": 1479,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#[unsafe(no_mangle)]\nextern \"C\" fn _ffi_fn_get_string() -> _"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_struct_in_2021/ffi.cpp",
    "chars": 829,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#include \"ffi.h\"\n\nextern \"C\" {\n\nint32_t _ffi_fn_empty_tuple("
  },
  {
    "path": "src/tests/snapshots/cpp_fn_struct_in_2021/ffi.h",
    "chars": 496,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#pragma once\n\n#include <stdint.h>\n\nnamespace rust {\n\nstruct "
  },
  {
    "path": "src/tests/snapshots/cpp_fn_struct_in_2021/miniffi.rs",
    "chars": 614,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#[no_mangle]\nextern \"C\" fn _ffi_fn_empty_tuple(x: i32, y: i3"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_struct_in_2024/ffi.cpp",
    "chars": 829,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#include \"ffi.h\"\n\nextern \"C\" {\n\nint32_t _ffi_fn_empty_tuple("
  },
  {
    "path": "src/tests/snapshots/cpp_fn_struct_in_2024/ffi.h",
    "chars": 496,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#pragma once\n\n#include <stdint.h>\n\nnamespace rust {\n\nstruct "
  },
  {
    "path": "src/tests/snapshots/cpp_fn_struct_in_2024/miniffi.rs",
    "chars": 646,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#[unsafe(no_mangle)]\nextern \"C\" fn _ffi_fn_empty_tuple(x: i3"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_struct_out_2021/ffi.cpp",
    "chars": 1109,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#include \"ffi.h\"\n\nstruct _ffi_ret_2_f32 {\n    float _0;\n    "
  },
  {
    "path": "src/tests/snapshots/cpp_fn_struct_out_2021/ffi.h",
    "chars": 835,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#pragma once\n\n#include <stdint.h>\n\nnamespace rust {\n\nstruct "
  },
  {
    "path": "src/tests/snapshots/cpp_fn_struct_out_2021/miniffi.rs",
    "chars": 547,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#[no_mangle]\nextern \"C\" fn _ffi_fn_empty_struct() {\n    _ = "
  },
  {
    "path": "src/tests/snapshots/cpp_fn_struct_out_2024/ffi.cpp",
    "chars": 1109,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#include \"ffi.h\"\n\nstruct _ffi_ret_2_f32 {\n    float _0;\n    "
  },
  {
    "path": "src/tests/snapshots/cpp_fn_struct_out_2024/ffi.h",
    "chars": 835,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#pragma once\n\n#include <stdint.h>\n\nnamespace rust {\n\nstruct "
  },
  {
    "path": "src/tests/snapshots/cpp_fn_struct_out_2024/miniffi.rs",
    "chars": 579,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#[unsafe(no_mangle)]\nextern \"C\" fn _ffi_fn_empty_struct() {\n"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_tuple_in_2021/ffi.cpp",
    "chars": 1209,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#include \"ffi.h\"\n\nextern \"C\" {\n\nint32_t _ffi_fn_empty_tuple("
  },
  {
    "path": "src/tests/snapshots/cpp_fn_tuple_in_2021/ffi.h",
    "chars": 497,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#pragma once\n\n#include <stdint.h>\n#include <tuple>\n\nnamespac"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_tuple_in_2021/miniffi.rs",
    "chars": 666,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#[no_mangle]\nextern \"C\" fn _ffi_fn_empty_tuple(x: i32, y: i3"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_tuple_in_2024/ffi.cpp",
    "chars": 1209,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#include \"ffi.h\"\n\nextern \"C\" {\n\nint32_t _ffi_fn_empty_tuple("
  },
  {
    "path": "src/tests/snapshots/cpp_fn_tuple_in_2024/ffi.h",
    "chars": 497,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#pragma once\n\n#include <stdint.h>\n#include <tuple>\n\nnamespac"
  },
  {
    "path": "src/tests/snapshots/cpp_fn_tuple_in_2024/miniffi.rs",
    "chars": 706,
    "preview": "// This file was generated by miniffi v0.1.0. Do not edit.\n\n#[unsafe(no_mangle)]\nextern \"C\" fn _ffi_fn_empty_tuple(x: i3"
  }
]

// ... and 615 more files (download for full content)

About this extraction

This page contains the full source code of the evanw/miniffi GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 815 files (2.4 MB), approximately 673.5k tokens, and a symbol index with 5666 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!