Crate postcompile

Source
Expand description

A crate which allows you to compile Rust code at runtime (hence the name postcompile).

What that means is that you can provide the input to rustc and then get back the expanded output, compiler errors, warnings, etc.

This is particularly useful when making snapshot tests of proc-macros, look below for an example with the insta crate.

See the changelog for a full release history.

§Feature flags

  • docs — Enables changelog and documentation of feature flags

§Usage

#[test]
fn some_cool_test() {
    assert_snapshot!(postcompile::compile!({
        #![allow(unused)]

        #[derive(Debug, Clone)]
        struct Test {
            a: u32,
            b: i32,
        }

        const TEST: Test = Test { a: 1, b: 3 };
    }));
}

#[test]
fn some_cool_test_extern() {
    assert_snapshot!(postcompile::compile_str!(include_str!("some_file.rs")));
}

#[test]
fn test_inside_test() {
    assert_snapshot!(postcompile::compile!(
        postcompile::config! {
            test: true,
        },
        {
            fn add(a: i32, b: i32) -> i32 {
                a + b
            }

            #[test]
            fn test_add() {
                assert_eq!(add(1, 2), 3);
            }
        },
    ));
}

#[test]
fn test_inside_test_with_tokio() {
    assert_snapshot!(postcompile::compile!(
        postcompile::config! {
            test: true,
            dependencies: vec![
                postcompile::Dependency::version("tokio", "1").feature("full")
            ]
        },
        {
            async fn async_add(a: i32, b: i32) -> i32 {
                a + b
            }

            #[tokio::test]
            async fn test_add() {
                assert_eq!(async_add(1, 2).await, 3);
            }
        },
    ));
}

§Features

  • Cached builds: This crate reuses the cargo build cache of the original crate so that only the contents of the macro are compiled & not any additional dependencies.
  • Coverage: This crate works with cargo-llvm-cov out of the box, which allows you to instrument the proc-macro expansion.
  • Testing: You can define tests with the #[test] macro and the tests will run on the generated code.

§Alternatives

  • compiletest_rs: This crate is used by the Rust compiler team to test the compiler itself. Not really useful for proc-macros.
  • trybuild: This crate is an all-in-one solution for testing proc-macros, with built in snapshot testing.
  • ui_test: Similar to trybuild with a slightly different API & used by the Rust compiler team to test the compiler itself.

§Differences

The other libraries are focused on testing & have built in test harnesses. This crate takes a step back and allows you to compile without a testing harness. This has the advantage of being more flexible, and allows you to use whatever testing framework you want.

In the examples above I showcase how to use this crate with the insta crate for snapshot testing.

§Limitations

Please note that this crate does not work inside a running compiler process (inside a proc-macro) without hacky workarounds and complete build-cache invalidation.

This is because cargo holds a lock on the build directory and that if we were to compile inside a proc-macro we would recursively invoke the compiler.

§License

This project is licensed under the MIT or Apache-2.0 license. You can choose between one of them if you use this work.

SPDX-License-Identifier: MIT OR Apache-2.0

Modules§

changelog
Changelogs generated by scuffle_changelog

Enums§

ExitStatus
The return status of the compilation.

Structs§

CompileOutput
The output of the compilation.

Functions§

compile_custom
Compiles the given tokens and returns the output.

Structs§

Config
The configuration for the compilation.
Dependency
A dependency to apply to the code

Macros§

config
Define a config to use when compiling crates. This macro is allows you to provide values for the config items.
compile
Compiles the given tokens and returns the output.
compile_str
Compiles the given string of tokens and returns the output.
try_compile
Compiles the given string of tokens and returns the output.
try_compile_str
Compiles the given string of tokens and returns the output.